diff --git a/client/src/components/App.js b/client/src/components/App.js index 3f402af..d2ab917 100644 --- a/client/src/components/App.js +++ b/client/src/components/App.js @@ -1,13 +1,9 @@ -// import logo from './../logo.svg'; -// import './../styles/App.css'; - -import React, { Component } from 'react'; -import AppointmentList from './AppointmentList'; -import CreateAppointment from './CreateAppointment' +import React from 'react'; +// import CreateAppointment from './CreateAppointment'; import Header from './Header'; -import Login from './Login' -import Search from './Search'; -import { Redirect, Route, Switch } from 'react-router-dom'; +// import AppointmentList from './AppointmentList'; +import ProductList from './ProductList'; +import { Switch, Route } from 'react-router-dom'; const App = () => { return ( @@ -15,19 +11,9 @@ const App = () => {
- - - - - + + {/* */} + {/* */}
@@ -35,3 +21,42 @@ const App = () => { }; export default App; + + +// // import logo from './../logo.svg'; +// // import './../styles/App.css'; + +// import React, { Component } from 'react'; +// import AppointmentList from './AppointmentList'; +// import CreateAppointment from './CreateAppointment' +// // import Header from './Header'; +// import Login from './Login' +// import Search from './Search'; +// import { Redirect, Route, Switch } from 'react-router-dom'; + +// const App = () => { +// return ( +//
+//
+//
+// +// +// +// +// +// +// +//
+//
+// ); +// }; + +// export default App; diff --git a/client/src/components/AppointmentList.js b/client/src/components/AppointmentList.js index 5bb4fa7..1019b98 100644 --- a/client/src/components/AppointmentList.js +++ b/client/src/components/AppointmentList.js @@ -6,56 +6,56 @@ import { useQuery, gql } from '@apollo/client'; import { Link } from 'react-router-dom'; export const FEED_QUERY = gql` - query FeedQuery( + query AppointmentManyQuery( $take: Int $skip: Int $orderBy: AppointmentOrderByInput ) { - feed(take: $take, skip: $skip, orderBy: $orderBy) { + appointmentMany(take: $take, skip: $skip, orderBy: $orderBy) { id appointments { id createdAt title - start - end + # start + # end description - createdBy { - id - name - } - follows { - id - user { - id - } - } + # createdBy { + # id + # name + # } + # follows { + # id + # user { + # id + # } + # } } count } } `; -const NEW_APPOINTMENTS_SUBSCRIPTION = gql` - subscription { - newAppointment { - id - url - description - createdAt - createdBy { - id - name - } - follows { - id - user { - id - } - } - } - } -`; +// const NEW_APPOINTMENTS_SUBSCRIPTION = gql` +// subscription { +// newAppointment { +// id +// url +// description +// createdAt +// createdBy { +// id +// name +// } +// follows { +// id +// user { +// id +// } +// } +// } +// } +// `; const getQueryVariables = (isNewPage, page) => { const skip = isNewPage ? (page - 1) * APPOINTMENTS_PER_PAGE : 0; @@ -102,25 +102,25 @@ const AppointmentList = () => { return rankedAppointments; }; - subscribeToMore({ - document: NEW_APPOINTMENTS_SUBSCRIPTION, - updateQuery: (prev, { subscriptionData }) => { - if (!subscriptionData.data) return prev; - const newAppointment = subscriptionData.data.newAppointment; - const exists = prev.feed.appointments.find( - ({ id }) => id === newAppointment.id - ); - if (exists) return prev; + // subscribeToMore({ + // document: NEW_APPOINTMENTS_SUBSCRIPTION, + // updateQuery: (prev, { subscriptionData }) => { + // if (!subscriptionData.data) return prev; + // const newAppointment = subscriptionData.data.newAppointment; + // const exists = prev.feed.appointments.find( + // ({ id }) => id === newAppointment.id + // ); + // if (exists) return prev; - return Object.assign({}, prev, { - feed: { - appointments: [newAppointment, ...prev.feed.appointments], - count: prev.feed.appointments.length + 1, - __typename: prev.feed.__typename - } - }); - } - }); + // return Object.assign({}, prev, { + // feed: { + // appointments: [newAppointment, ...prev.feed.appointments], + // count: prev.feed.appointments.length + 1, + // __typename: prev.feed.__typename + // } + // }); + // } + // }); return ( <> diff --git a/client/src/components/Header.js b/client/src/components/Header.js index 2bba25a..ce7b572 100644 --- a/client/src/components/Header.js +++ b/client/src/components/Header.js @@ -1,11 +1,9 @@ import React from 'react'; import { useHistory } from 'react-router'; -import { Link } from 'react-router-dom'; -import { AUTH_TOKEN } from '../constants'; +import { Link, withRouter } from 'react-router-dom'; const Header = () => { const history = useHistory(); - const authToken = localStorage.getItem(AUTH_TOKEN); return (
@@ -14,47 +12,15 @@ const Header = () => { new
|
- - top - -
|
- - search - - {authToken && ( -
-
|
- - submit - -
- )} -
-
- {authToken ? ( -
{ - localStorage.removeItem(AUTH_TOKEN); - history.push(`/`); - }} - > - logout -
- ) : ( - - login - - )} + + submit +
); }; -export default Header; +export default Header; \ No newline at end of file diff --git a/client/src/components/Product.js b/client/src/components/Product.js new file mode 100644 index 0000000..53d6e1b --- /dev/null +++ b/client/src/components/Product.js @@ -0,0 +1,14 @@ +import React from 'react'; + +const Product = (props) => { + const { product } = props; + return ( +
+
+ {product.title}: only {product.qty}! +
+
+ ); +}; + +export default Product; \ No newline at end of file diff --git a/client/src/components/ProductList.js b/client/src/components/ProductList.js new file mode 100644 index 0000000..44bfeee --- /dev/null +++ b/client/src/components/ProductList.js @@ -0,0 +1,29 @@ +import React from 'react'; +import Product from './Product'; +import { useQuery, gql } from '@apollo/client'; + +const FEED_QUERY = gql` + { + allProducts{ + title + qty + } + } +`; + +const ProductList = () => { + + const { data } = useQuery(FEED_QUERY); + + console.log("Fah!", data); + + return ( +
+ {data.allProducts.map((product) => ( + + ))} +
+ ); +}; + +export default ProductList; \ No newline at end of file diff --git a/client/src/components/Search.js b/client/src/components/Search.js index 7198fa0..1de932f 100644 --- a/client/src/components/Search.js +++ b/client/src/components/Search.js @@ -52,10 +52,10 @@ const Search = () => { OK - {data && + {/* {data && data.feed.appointments.map((appointment, index) => ( - ))} + ))} */} ); }; diff --git a/client/src/index.js b/client/src/index.js index 09425bf..4785511 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -2,6 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import './styles/index.css'; import App from './components/App'; +import { BrowserRouter } from 'react-router-dom'; // import * as serviceWorker from './serviceWorker'; // 1 @@ -14,7 +15,7 @@ import { // 2 const httpLink = createHttpLink({ - uri: 'http://localhost:4000' + uri: 'http://localhost:5000/graphql' }); // 3 @@ -25,9 +26,11 @@ const client = new ApolloClient({ // 4 ReactDOM.render( - - - , + + + + + , document.getElementById('root') ); // serviceWorker.unregister(); diff --git a/server/src/index.js b/server/src/index.js index 75611d4..1bf2c68 100644 --- a/server/src/index.js +++ b/server/src/index.js @@ -7,18 +7,20 @@ import schema from './schema.js'; import './utils/db.js'; import fs from 'fs'; import path from 'path'; +import cors from 'cors'; const moduleURL = new URL(import.meta.url); const __dirname = path.dirname(moduleURL.pathname); const app = express(); const pubsub = new PubSub(); -const PORT = 4000; dotenv.config(); +app.use(cors()); + app.get('/', (req, res) => { res.json({ - msg: 'Welcome to GraphQL' + msg: 'GraphQL home!' }) }); @@ -28,32 +30,33 @@ app.use('/graphql', graphqlHTTP({ })); const server = new ApolloServer({ - typeDefs: fs.readFileSync( - path.join(__dirname, 'schema.graphql'), - 'utf8' - ), + // typeDefs: fs.readFileSync( + // path.join(__dirname, 'schema.graphql'), + // 'utf8' + // ), + schema, cors: true, playground: process.env.NODE_ENV === 'development' ? true : false, - 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) - // } + // 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 { - ...req, - mongoose, - // pubsub, - // userId: - // req && req.headers.authorization - // ? getUserId(req) - // : null - } - }, + // return { + // ...req, + // mongoose, + // pubsub, + // userId: + // req && req.headers.authorization + // ? getUserId(req) + // : null + // } + // }, // subscriptions: { // onConnect: (connectionParams) => { // if (connectionParams.authToken) { diff --git a/server/src/resolvers.js b/server/src/resolvers.js index 9af9d6c..2d64476 100644 --- a/server/src/resolvers.js +++ b/server/src/resolvers.js @@ -1,41 +1,38 @@ import Product from './models/product.js'; -// import User from './resolvers/User.js'; -// import Appointment from './resolvers/Appointment.js'; -// import Follow from './resolvers/Follow.js'; -// import Query from './resolvers/Query.js'; -// import Mutation from './resolvers/Mutation.js'; -// import Subscription from './resolvers/Subscription.js'; + export const resolvers = { Query: { async allProducts() { - return await Product.find(); + const products = await Product.find(); + console.log("Tah!", products); + return products; + // return { + // products + // }; + }, + }, + Mutation: { + async createProduct(root, { + input + }) { + return await Product.create(input); + }, + async updateProduct(root, { + _id, + input + }) { + return await Product.findOneAndUpdate({ + _id + }, input, { + new: true + }) + }, + async deleteProduct(root, { + _id + }) { + return await Product.findOneAndRemove({ + _id + }); }, - - // async feed(parent, args, context, info) { - - // const where = args.filter - // ? { - // OR: [ - // { title: { contains: args.filter } }, - // { description: { contains: args.filter } } - // ] - // } - // : {}; - // console.log(context.mongo); - // const appointments = await context.mongo.appointment.findMany({ - // where, - // skip: args.skip, - // take: args.take, - // orderBy: args.orderBy - // }); - - // const count = await context.mongo.appointment.count({ where }); - - // return { - // id: 'main-feed', - // appointments, - // count - // }; - // } } }; \ No newline at end of file diff --git a/server/src/schema.graphql b/server/src/schema.graphql index a03e02a..ef61707 100644 --- a/server/src/schema.graphql +++ b/server/src/schema.graphql @@ -7,7 +7,7 @@ type Query { orderBy: AppointmentOrderByInput ): Feed! allProducts: [Product] - # users: [User!]! + users: [User!]! } type Feed { @@ -22,7 +22,17 @@ type Mutation { description: String!, start: DateTime!, end: DateTime!, - ): Appointment! + ): Appointment! + createProduct( + input: ProductInput + ) : Product + updateProduct( + _id: ID!, + input: ProductInput + ): Product + deleteProduct( + _id: ID! + ) : Product signup( email: String! password: String! @@ -68,7 +78,7 @@ type Appointment { type Product { id: ID! title: String! - qty: Integer + qty: Int } type Follow { @@ -77,6 +87,12 @@ type Follow { user: User! } +input ProductInput { + title: String! + qty: Int + } + + input AppointmentOrderByInput { description: Sort url: Sort @@ -88,5 +104,4 @@ enum Sort { desc } -scalar Integer scalar DateTime diff --git a/server/src/schema.js b/server/src/schema.js index 9293723..ff5def4 100644 --- a/server/src/schema.js +++ b/server/src/schema.js @@ -1,45 +1,54 @@ -import { - makeExecutableSchema -} from 'graphql-tools'; -import { - resolvers -} from './resolvers.js'; - -import fs from 'fs'; -import path from 'path'; - -const moduleURL = new URL(import.meta.url); -const __dirname = path.dirname(moduleURL.pathname); - -const typeDefs = fs.readFileSync( - path.join(__dirname, 'schema.graphql'), - 'utf8' -); -const schema = makeExecutableSchema({ - typeDefs, - // resolvers -}); -export default schema; - - // import { // makeExecutableSchema // } from 'graphql-tools'; // import { // resolvers // } from './resolvers.js'; -// const typeDefs = ` -// type Product { -// _id: ID! -// title: String! -// qty: Int -// } -// type Query { -// allProducts: [Product] -// } -// `; + +// import fs from 'fs'; +// import path from 'path'; + +// const moduleURL = new URL(import.meta.url); +// const __dirname = path.dirname(moduleURL.pathname); + +// const typeDefs = fs.readFileSync( +// path.join(__dirname, 'schema.graphql'), +// 'utf8' +// ); // const schema = makeExecutableSchema({ // typeDefs, -// resolvers +// // resolvers // }); -// export default schema; \ No newline at end of file +// export default schema; + + +import { + makeExecutableSchema +} from 'graphql-tools'; +import { + resolvers +} from './resolvers.js'; +const typeDefs = ` +type Product { + _id: ID! + title: String! + qty: Int + } +type Query { + allProducts: [Product] + } + input ProductInput { + title: String! + qty: Int + } +type Mutation { + createProduct(input: ProductInput) : Product + updateProduct(_id: ID!, input: ProductInput): Product + deleteProduct(_id: ID!) : Product + } +`; +const schema = makeExecutableSchema({ + typeDefs, + resolvers +}); +export default schema; \ No newline at end of file diff --git a/server/src/schema/index.js b/server/src/schema/index.js deleted file mode 100644 index 72db71f..0000000 --- a/server/src/schema/index.js +++ /dev/null @@ -1,20 +0,0 @@ -import { SchemaComposer } from 'graphql-compose'; - -import db from '../utils/db.js'; - -const schemaComposer = new SchemaComposer(); - -import { UserQuery, UserMutation } from './user.js'; -import { AppointmentQuery, AppointmentMutation } from './appointment.js'; - -schemaComposer.Query.addFields({ - ...UserQuery, - ...AppointmentQuery, -}); - -schemaComposer.Mutation.addFields({ - ...UserMutation, - ...AppointmentMutation, -}); - -export default schemaComposer.buildSchema(); \ No newline at end of file