From c752e3ec80881b4c4f9c8a5a8e84cc0121343931 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Sat, 2 Jan 2021 18:37:03 +0100 Subject: [PATCH] Appointment with Mongo --- client/src/components/App.js | 31 +--- client/src/components/AppointmentList.js | 4 +- client/src/components/CreateAppointment.js | 8 +- server/src/graphql/models/appointment.js | 31 ++++ server/src/graphql/models/user.js | 36 ++++ server/src/graphql/resolvers/appointment.js | 36 ++++ server/src/graphql/resolvers/user.js | 36 ++++ server/src/graphql/schema/schema.js | 53 ++++++ server/src/index.js | 193 ++++++++++++-------- server/src/resolvers/Mutation.js | 2 +- server/src/resolvers/Query.js | 2 +- server/src/schema.graphql | 10 +- 12 files changed, 330 insertions(+), 112 deletions(-) create mode 100644 server/src/graphql/models/appointment.js create mode 100644 server/src/graphql/models/user.js create mode 100644 server/src/graphql/resolvers/appointment.js create mode 100644 server/src/graphql/resolvers/user.js create mode 100644 server/src/graphql/schema/schema.js diff --git a/client/src/components/App.js b/client/src/components/App.js index a57c6cf..3f402af 100644 --- a/client/src/components/App.js +++ b/client/src/components/App.js @@ -3,7 +3,7 @@ import React, { Component } from 'react'; import AppointmentList from './AppointmentList'; -import CreateLink from './CreateAppointment' +import CreateAppointment from './CreateAppointment' import Header from './Header'; import Login from './Login' import Search from './Search'; @@ -19,7 +19,7 @@ const App = () => { @@ -34,31 +34,4 @@ const App = () => { ); }; -// class App extends Component { -// render() { -// return ; -// } -// } - -// function App() { -// return ( -//
-//
-// logo -//

-// Edit src/App.js and save to reload. -//

-// -// Learn React -// -//
-//
-// ); -// } - export default App; diff --git a/client/src/components/AppointmentList.js b/client/src/components/AppointmentList.js index cb7cf40..5bb4fa7 100644 --- a/client/src/components/AppointmentList.js +++ b/client/src/components/AppointmentList.js @@ -61,7 +61,7 @@ const getQueryVariables = (isNewPage, page) => { const skip = isNewPage ? (page - 1) * APPOINTMENTS_PER_PAGE : 0; const take = isNewPage ? APPOINTMENTS_PER_PAGE : 100; const orderBy = { createdAt: 'desc' }; - console.log(isNewPage, page, APPOINTMENTS_PER_PAGE, skip, take, orderBy); + return { take, skip, orderBy }; }; @@ -78,8 +78,6 @@ const AppointmentList = () => { pageIndexParams[pageIndexParams.length - 1] ); - console.log(pageIndexParams.length, page); - const pageIndex = page ? (page - 1) * APPOINTMENTS_PER_PAGE : 0; const { diff --git a/client/src/components/CreateAppointment.js b/client/src/components/CreateAppointment.js index ad44502..7e14141 100644 --- a/client/src/components/CreateAppointment.js +++ b/client/src/components/CreateAppointment.js @@ -6,14 +6,14 @@ import { FEED_QUERY } from './AppointmentList'; const CREATE_APPOINTMENT_MUTATION = gql` mutation CreateAppointmentMutation( + $title: String! $description: String! - $url: String! ) { - createAppointment(description: $description, url: $url) { + createAppointment(title: $title, description: $description) { id - createdAt - url + title description + createdAt } } `; diff --git a/server/src/graphql/models/appointment.js b/server/src/graphql/models/appointment.js new file mode 100644 index 0000000..f6cf5c6 --- /dev/null +++ b/server/src/graphql/models/appointment.js @@ -0,0 +1,31 @@ +const mongoose = require("mongoose") + +const Schema = mongoose.Schema + +const appointmentSchema = new Schema( + { + title: { + type: String, + required: true, + }, + + description: { + type: String, + required: true, + }, + + timeStart: { + type: Date, + required: true, + }, + + timeEnd: { + type: Date, + required: true, + }, + + }, + { timestamps: true } +) + +module.exports = mongoose.model("Appointment", appointmentSchema) \ No newline at end of file diff --git a/server/src/graphql/models/user.js b/server/src/graphql/models/user.js new file mode 100644 index 0000000..afc5b8c --- /dev/null +++ b/server/src/graphql/models/user.js @@ -0,0 +1,36 @@ +const mongoose = require("mongoose") + +const Schema = mongoose.Schema + +const userSchema = new Schema( + { + firstName: { + type: String, + required: true, + }, + + lastName: { + type: String, + required: true, + }, + + password: { + type: String, + required: true, + }, + + email: { + type: String, + required: true, + }, + + isActive: { + type: Boolean, + required: true, + default: 1 + }, + }, + { timestamps: true } +) + +module.exports = mongoose.model("User", userSchema) \ No newline at end of file diff --git a/server/src/graphql/resolvers/appointment.js b/server/src/graphql/resolvers/appointment.js new file mode 100644 index 0000000..eef5007 --- /dev/null +++ b/server/src/graphql/resolvers/appointment.js @@ -0,0 +1,36 @@ +// const { default: Appointment } = require("../../../../client/src/components/Appointment") +const { newAppointment } = require("../../resolvers/Subscription") +const Appointment = require("../models/appointment") + +module.exports = { + findAppointments: async () => { + try { + const appointmentsFetched = await Appointment.find() + return appointmentsFetched.map(appointment => { + return { + ...this.appointment._doc, + _id: appointment.id, + createdAt: new Date(appointment._doc.createdAt).toISOString(), + } + }) + } catch (error) { + throw error + } + }, + + createAppointment: async args => { + try { + const { title, description, timeStart, timeEnd } = args.appointment + const appointment = new Appointment({ + title, + description, + timeStart, + timeEnd + }) + const newAppointment = await appointment.save() + return { ...newAppointment._doc, _id: newAppointment.id } + } catch (error) { + throw error + } + }, +} \ No newline at end of file diff --git a/server/src/graphql/resolvers/user.js b/server/src/graphql/resolvers/user.js new file mode 100644 index 0000000..c318e86 --- /dev/null +++ b/server/src/graphql/resolvers/user.js @@ -0,0 +1,36 @@ +// const { default: Appointment } = require("../../../../client/src/components/Appointment") +// const { newUser } = require("../../resolvers/Subscription") +const User = require("../models/user") + +module.exports = { + findUsers: async () => { + try { + const usersFetched = await User.find() + return usersFetched.map(user => { + return { + ...this.user._doc, + _id: user.id, + createdAt: new Date(user._doc.createdAt).toISOString(), + } + }) + } catch (error) { + throw error + } + }, + + createUser: async args => { + try { + const { firstName, lastName, email, isActive } = args.user + const user = new User({ + firstName, + lastName, + email, + isActive + }) + const newUser = await user.save() + return { ...newUser._doc, _id: newUser.id } + } catch (error) { + throw error + } + }, +} \ No newline at end of file diff --git a/server/src/graphql/schema/schema.js b/server/src/graphql/schema/schema.js new file mode 100644 index 0000000..0701576 --- /dev/null +++ b/server/src/graphql/schema/schema.js @@ -0,0 +1,53 @@ +const { buildSchema } = require("graphql") + +module.exports = buildSchema(` + type User { + _id: ID! + firstName: String! + lastName: String! + email: String! + password: String! + isActive: Boolean! + } + + input UserInput { + firstName: String! + lastName: String! + email: String! + password: String! + isActive: Boolean! + } + + type Appointment { + _id: ID! + title: String! + description: String! + timeStart: Date! + timeEnd: Date! + createdAt: String! + } + + input AppointmentInput { + title: String! + description: String! + timeStart: Date! + timeEnd: Date! + } + + type Query { + findAppointments:[Appointment!] + findUsers:[User!]! + } + + type Mutation { + createAppointment(appointment:AppointmentInput): Appointment + createUser(user:UserInput): User + } + + schema { + query: Query + mutation: Mutation + } + + scalar Date +`) \ No newline at end of file diff --git a/server/src/index.js b/server/src/index.js index 6bdf207..e240e2c 100644 --- a/server/src/index.js +++ b/server/src/index.js @@ -1,4 +1,14 @@ const { ApolloServer, PubSub } = require('apollo-server'); +// const { Cors } = require('cors'); +// const { Express } = require('express'); + +const express = require("express"); +const { graphqlHTTP } = require('express-graphql'); +const mongoose = require("mongoose"); +const graphqlSchema = require("./graphql/schema/schema") +const appointmentResolvers = require("./graphql/resolvers/appointment") +const userResolvers = require("./graphql/resolvers/user") + var MongoClient = require('mongodb', { useUnifiedTopology: true }).MongoClient; // import { MongoClient } from 'mongodb' const Query = require('./resolvers/Query'); @@ -13,87 +23,126 @@ const { getUserId } = require('./utils'); const pubsub = new PubSub(); +const app = express() + +const graphqlResolvers = { + appointmentResolvers, + userResolvers +}; + + +app.use( + "/graphql", + graphqlHTTP({ + schema: graphqlSchema, + rootValue: appointmentResolvers, + graphiql: true, + }) +) +const uri = `mongodb+srv://admin:hEbAjhvkrFDHAP3@cluster0.0hjtt.mongodb.net/Calendar?retryWrites=true&w=majority` +const options = { useNewUrlParser: true, useUnifiedTopology: true } +let db = mongoose + .connect(uri, options) + .then(() => app.listen(4000, console.log("Server is running"))) + .catch(error => { + throw error + }) + +// const app = new Express(); +// app.use(Cors()); + // const mongo = new MongoClient({ // errorFormat: 'minimal' // }); -const mongo = MongoClient.connect("mongodb+srv://admin:hEbAjhvkrFDHAP3@cluster0.0hjtt.mongodb.net/Calendar?retryWrites=true&w=majority", function (err, db) { +// const mongo = MongoClient.connect("mongodb+srv://admin:hEbAjhvkrFDHAP3@cluster0.0hjtt.mongodb.net/Calendar?retryWrites=true&w=majority", function (err, db) { - if (err) throw err; - console.log("ALL good"); - //Write databse Insert/Update/Query code here.. +// if (err) throw err; +// console.log("ALL good"); +// //Write databse Insert/Update/Query code here.. -}); +// }); -const resolvers = { - Query, - Mutation, - Subscription, - User, - Appointment, - Follow -}; +// const dbClient = new MongoClient( +// 'mongodb+srv://admin:hEbAjhvkrFDHAP3@cluster0.0hjtt.mongodb.net/Calendar?retryWrites=true&w=majority', +// { +// useNewUrlParser: true, +// useUnifiedTopology: true, +// } +// ) -let db; +// const resolvers = { +// Query, +// Mutation, +// Subscription, +// User, +// Appointment, +// Follow +// }; -const server = new ApolloServer({ - typeDefs: fs.readFileSync( - path.join(__dirname, 'schema.graphql'), - 'utf8' - ), - resolvers, - // context: async () => { - // if (!db) { - // try { - // const dbClient = new MongoClient( - // 'mongodb+srv://test:qwerty123@cluster0-yvwjx.mongodb.net/next-graphql?retryWrites=true&w=majority', - // { - // useNewUrlParser: true, - // useUnifiedTopology: true, - // } - // ) +// let db; - // if (!dbClient.isConnected()) await dbClient.connect() - // db = dbClient.db('next-graphql') // database name - // } catch (e) { - // console.log('--->error while connecting with graphql context (db)', e) - // } - // } +// const server = new ApolloServer({ +// typeDefs: fs.readFileSync( +// path.join(__dirname, 'schema.graphql'), +// 'utf8' +// ), +// resolvers, +// context: async ({ req }) => { +// if (!db) { +// try { +// if (!dbClient.isConnected()) await dbClient.connect() +// mongo = dbClient.db('Calendar') // database name +// console.log(db); +// } catch (e) { +// console.log('--->error while connecting with graphql context (db)', e) +// } +// } - // return { db } - // }, - context: ({ req }) => { - return { - ...req, - mongo, - pubsub, - userId: - req && req.headers.authorization - ? getUserId(req) - : null - }; - }, - subscriptions: { - onConnect: (connectionParams) => { - if (connectionParams.authToken) { - return { - mongo, - userId: getUserId( - null, - connectionParams.authToken - ) - }; - } else { - return { - mongo - }; - } - } - } -}); +// return { +// ...req, +// mongo, +// pubsub, +// userId: +// req && req.headers.authorization +// ? getUserId(req) +// : null +// } +// }, +// // context: ({ req }) => { +// // return { +// // ...req, +// // mongo, +// // pubsub, +// // userId: +// // req && req.headers.authorization +// // ? getUserId(req) +// // : null +// // }; +// // }, +// // subscriptions: { +// // onConnect: (connectionParams) => { +// // if (connectionParams.authToken) { +// // return { +// // mongo, +// // userId: getUserId( +// // null, +// // connectionParams.authToken +// // ) +// // }; +// // } else { +// // return { +// // mongo +// // }; +// // } +// // } +// // } +// }); -server - .listen() - .then(({ url }) => - console.log(`Server is running on ${url}`) - ); +// // server.applyMiddleware({ app }); + +// server +// .listen() +// .then(({ url }) => +// console.log(`Server is running on ${url}`) +// ); diff --git a/server/src/resolvers/Mutation.js b/server/src/resolvers/Mutation.js index 3abe782..f40f62b 100644 --- a/server/src/resolvers/Mutation.js +++ b/server/src/resolvers/Mutation.js @@ -17,7 +17,7 @@ function createAppointment(parent, args, context, info) { } async function signup(parent, args, context, info) { - console.log(context); + console.log(context.mongo); const password = await bcrypt.hash(args.password, 10); const user = await context.mongo.user.create({ data: { ...args, password } diff --git a/server/src/resolvers/Query.js b/server/src/resolvers/Query.js index d064a77..b68f879 100644 --- a/server/src/resolvers/Query.js +++ b/server/src/resolvers/Query.js @@ -1,5 +1,5 @@ async function feed(parent, args, context, info) { - console.log(context); + const where = args.filter ? { OR: [ diff --git a/server/src/schema.graphql b/server/src/schema.graphql index ed659f5..5bf97ad 100644 --- a/server/src/schema.graphql +++ b/server/src/schema.graphql @@ -6,6 +6,7 @@ type Query { take: Int orderBy: AppointmentOrderByInput ): Feed! + # users: [User!]! } type Feed { @@ -26,8 +27,13 @@ type Mutation { password: String! name: String! ): AuthPayload - login(email: String!, password: String!): AuthPayload - follow(appointmentId: ID!): Follow + login( + email: String!, + password: String! + ): AuthPayload + follow( + appointmentId: ID! + ): Follow } type Subscription {