Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5368f40b04 | ||
|
|
2f119e43bd | ||
|
|
78db95aa5f | ||
|
|
959c6dbc33 | ||
|
|
93169095c0 |
@@ -5,8 +5,8 @@ import AppointmentList from './appointment/AppointmentList';
|
|||||||
import CreateAppointment from './appointment/CreateAppointment';
|
import CreateAppointment from './appointment/CreateAppointment';
|
||||||
import UpdateAppointemnt from './appointment/UpdateAppointment';
|
import UpdateAppointemnt from './appointment/UpdateAppointment';
|
||||||
import Calendar from './Calendar';
|
import Calendar from './Calendar';
|
||||||
|
import Search from './Search';
|
||||||
import { Switch, Route } from 'react-router-dom';
|
import { Switch, Route } from 'react-router-dom';
|
||||||
// import ProductList from './ProductList';
|
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
@@ -14,12 +14,12 @@ const App = () => {
|
|||||||
<Header />
|
<Header />
|
||||||
<div className="ph3 pv1 background-gray">
|
<div className="ph3 pv1 background-gray">
|
||||||
<Switch>
|
<Switch>
|
||||||
{/* <Route exact path="/" component={ProductList} /> */}
|
|
||||||
<Route exact path="/" component={AppointmentList} />
|
<Route exact path="/" component={AppointmentList} />
|
||||||
<Route exact path="/create" component={CreateAppointment} />
|
<Route exact path="/create" component={CreateAppointment} />
|
||||||
<Route exact path="/update/:_id" component={UpdateAppointemnt} />
|
<Route exact path="/update/:_id" component={UpdateAppointemnt} />
|
||||||
<Route exact path="/login" component={Login} />
|
<Route exact path="/login" component={Login} />
|
||||||
<Route exact path="/calendar" component={Calendar} />
|
<Route exact path="/calendar" component={Calendar} />
|
||||||
|
<Route exact path="/search" component={Search} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
const Product = (props) => {
|
|
||||||
const { product } = props;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<b>{product.title}</b>: only {product.qty}!
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Product;
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
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("Data:", data);
|
|
||||||
|
|
||||||
if (data !== undefined) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
data.allProducts.map((product) => (
|
|
||||||
<Product key={product.id} product={product} />
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
Rendering...
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProductList;
|
|
||||||
@@ -1,29 +1,16 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useMutation } from '@apollo/client';
|
|
||||||
import { useLazyQuery } from '@apollo/client';
|
import { useLazyQuery } from '@apollo/client';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import Appointment from './Appointment';
|
import Appointment from './appointment/Appointment';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
const FEED_SEARCH_QUERY = gql`
|
const FEED_SEARCH_QUERY = gql`
|
||||||
query FeedSearchQuery($filter: String!) {
|
query FeedSearchQuery($filter: String!) {
|
||||||
feed(filter: $filter) {
|
feed(filter: $filter) {
|
||||||
id
|
id
|
||||||
links {
|
appointments {
|
||||||
id
|
_id
|
||||||
title
|
title
|
||||||
description
|
description
|
||||||
type
|
|
||||||
createdBy {
|
|
||||||
id
|
|
||||||
username
|
|
||||||
}
|
|
||||||
# follows {
|
|
||||||
# id
|
|
||||||
# user {
|
|
||||||
# id
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,24 +25,13 @@ const Search = () => {
|
|||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
Search
|
Search
|
||||||
<input
|
<input type="text" onChange={(e) => setSearchFilter(e.target.value)}/>
|
||||||
type="text"
|
<button onClick={() => executeSearch({ variables: { filter: searchFilter } })}>OK</button>
|
||||||
onChange={(e) => setSearchFilter(e.target.value)}
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
onClick={() =>
|
|
||||||
executeSearch({
|
|
||||||
variables: { filter: searchFilter }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
OK
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
{/* {data &&
|
{data &&
|
||||||
data.feed.appointments.map((appointment, index) => (
|
data.feed.appointments.map((appointment, index) => (
|
||||||
<Link key={appointment.id} link={appointment} index={index} />
|
<Appointment key={appointment.id} appointment={appointment} index={index} />
|
||||||
))} */}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,15 +21,16 @@ const Appointment = (props) => {
|
|||||||
onCompleted: () => history.push('/')
|
onCompleted: () => history.push('/')
|
||||||
})
|
})
|
||||||
|
|
||||||
const updateAppointment = () => {
|
// const updateAppointment = () => {
|
||||||
let path = `/update/${appointment._id}`;
|
// let path = `/update/${appointment._id}`;
|
||||||
history.push(path);
|
// history.push(path);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<b>{appointment.title}</b> starts at {appointment.start}, ends at {appointment.end}. It is described as "{appointment.description}"<button onClick={deleteAppointment}>DELETE</button><button onClick={updateAppointment}>EDIT</button>
|
<b>{appointment.title}</b> starts at {appointment.start}, ends at {appointment.end}. It is described as "{appointment.description}"<button onClick={deleteAppointment}>DELETE</button>
|
||||||
|
{/* <button onClick={updateAppointment}>EDIT</button> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const APPOINTMENTS_QUERY = gql`
|
|||||||
|
|
||||||
const AppointmentList = () => {
|
const AppointmentList = () => {
|
||||||
|
|
||||||
const { data, loading } = useQuery(APPOINTMENTS_QUERY);
|
const { data } = useQuery(APPOINTMENTS_QUERY);
|
||||||
|
|
||||||
if (data !== undefined) {
|
if (data !== undefined) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -43,34 +43,34 @@ const CreateAppointment = () => {
|
|||||||
start: formState.start,
|
start: formState.start,
|
||||||
end: formState.end
|
end: formState.end
|
||||||
},
|
},
|
||||||
// update: (cache, { data: { createAppointment } }) => {
|
update: (cache, { data: { createAppointment } }) => {
|
||||||
// const take = APPOINTMENTS_PER_PAGE;
|
const take = APPOINTMENTS_PER_PAGE;
|
||||||
// const skip = 0;
|
const skip = 0;
|
||||||
// const orderBy = { createdAt: 'desc' };
|
const orderBy = { createdAt: 'desc' };
|
||||||
|
|
||||||
// const data = cache.readQuery({
|
const data = cache.readQuery({
|
||||||
// query: APPOINTMENTS_QUERY,
|
query: APPOINTMENTS_QUERY,
|
||||||
// variables: {
|
variables: {
|
||||||
// take,
|
take,
|
||||||
// skip,
|
skip,
|
||||||
// orderBy
|
orderBy
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
|
||||||
// cache.writeQuery({
|
cache.writeQuery({
|
||||||
// query: APPOINTMENTS_QUERY,
|
query: APPOINTMENTS_QUERY,
|
||||||
// data: {
|
data: {
|
||||||
// allAppointments: {
|
allAppointments: {
|
||||||
// appointments: [createAppointment, ...data.allAppointments]
|
appointments: [createAppointment, ...data.allAppointments]
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
// variables: {
|
variables: {
|
||||||
// take,
|
take,
|
||||||
// skip,
|
skip,
|
||||||
// orderBy
|
orderBy
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// },
|
},
|
||||||
onCompleted: () => history.push('/')
|
onCompleted: () => history.push('/')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
import { useMutation, gql, useQuery } from '@apollo/client';
|
import { useMutation, gql, useQuery } from '@apollo/client';
|
||||||
import { APPOINTMENTS_PER_PAGE } from '../../constants';
|
// import { APPOINTMENTS_PER_PAGE } from '../../constants';
|
||||||
import { APPOINTMENTS_QUERY } from './AppointmentList';
|
// import { APPOINTMENTS_QUERY } from './AppointmentList';
|
||||||
import Datetime from 'react-datetime';
|
import Datetime from 'react-datetime';
|
||||||
import "react-datetime/css/react-datetime.css";
|
import "react-datetime/css/react-datetime.css";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
import { Link, withRouter } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { AUTH_TOKEN } from '../../constants';
|
import { AUTH_TOKEN } from '../../constants';
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
@@ -17,6 +17,9 @@ const Header = () => {
|
|||||||
<div className="flex flex-fixed">
|
<div className="flex flex-fixed">
|
||||||
<Link to="/create" className="ml1 no-underline black">New</Link>
|
<Link to="/create" className="ml1 no-underline black">New</Link>
|
||||||
</div>
|
</div>
|
||||||
|
{/* <div className="flex flex-fixed">
|
||||||
|
<Link to="/search" className="ml1 no-underline black">Search</Link>
|
||||||
|
</div> */}
|
||||||
<div className="flex flex-fixed">
|
<div className="flex flex-fixed">
|
||||||
{authToken ? (
|
{authToken ? (
|
||||||
<div className="ml1 pointer black"
|
<div className="ml1 pointer black"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
} from '@apollo/client';
|
} from '@apollo/client';
|
||||||
|
|
||||||
const httpLink = createHttpLink({
|
const httpLink = createHttpLink({
|
||||||
uri: 'http://localhost:4000/djhb58fytkh476dk45yh49'
|
uri: 'http://localhost:4000/graphql'
|
||||||
});
|
});
|
||||||
|
|
||||||
const authLink = setContext((_, { headers }) => {
|
const authLink = setContext((_, { headers }) => {
|
||||||
|
|||||||
@@ -23,14 +23,14 @@
|
|||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"esm": "^3.2.25",
|
"esm": "^3.2.25",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-graphql": "^0.12.0",
|
"express-graphql": "*",
|
||||||
"graphql": "^15.4.0",
|
"graphql": "*",
|
||||||
"graphql-compose": "^7.23.0",
|
"graphql-compose": "*",
|
||||||
"graphql-compose-connection": "^8.0.1",
|
"graphql-compose-connection": "*",
|
||||||
"graphql-compose-mongoose": "^9.0.0",
|
"graphql-compose-mongoose": "*",
|
||||||
"graphql-depth-limit": "^1.1.0",
|
"graphql-depth-limit": "*",
|
||||||
"graphql-middleware": "^6.0.0",
|
"graphql-middleware": "*",
|
||||||
"graphql-tools": "^7.0.2",
|
"graphql-tools": "*",
|
||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "8.5.1",
|
||||||
"migrate": "^1.7.0",
|
"migrate": "^1.7.0",
|
||||||
"mocha": "^8.2.1",
|
"mocha": "^8.2.1",
|
||||||
|
|||||||
@@ -9,14 +9,17 @@ import './utils/db.js';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
// import getUserId from './utils';
|
|
||||||
|
|
||||||
|
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
const APP_SECRET = 'GraphQL-is-aw3some';
|
|
||||||
|
const moduleURL = new URL(import.meta.url);
|
||||||
|
const __dirname = path.dirname(moduleURL.pathname);
|
||||||
|
const app = express();
|
||||||
|
const pubsub = new PubSub();
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
function getTokenPayload(token) {
|
function getTokenPayload(token) {
|
||||||
return jwt.verify(token, APP_SECRET);
|
return jwt.verify(token, process.env.APP_SECRET);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserId(req, authToken) {
|
function getUserId(req, authToken) {
|
||||||
@@ -38,19 +41,10 @@ function getUserId(req, authToken) {
|
|||||||
throw new Error('Not authenticated');
|
throw new Error('Not authenticated');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const moduleURL = new URL(import.meta.url);
|
|
||||||
const __dirname = path.dirname(moduleURL.pathname);
|
|
||||||
const app = express();
|
|
||||||
const pubsub = new PubSub();
|
|
||||||
|
|
||||||
dotenv.config();
|
|
||||||
|
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
|
||||||
app.use('/djhb58fytkh476dk45yh49', graphqlHTTP({
|
app.use('/graphql', graphqlHTTP({
|
||||||
schema: schema,
|
schema,
|
||||||
validationRules: [depthLimit(3)],
|
validationRules: [depthLimit(3)],
|
||||||
graphiql: true
|
graphiql: true
|
||||||
}));
|
}));
|
||||||
@@ -63,17 +57,7 @@ const server = new ApolloServer({
|
|||||||
// schema,
|
// schema,
|
||||||
cors: true,
|
cors: true,
|
||||||
playground: process.env.NODE_ENV === 'development' ? true : false,
|
playground: process.env.NODE_ENV === 'development' ? true : false,
|
||||||
context: ({ req }) => {
|
context: ({ 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,
|
...req,
|
||||||
mongoose,
|
mongoose,
|
||||||
pubsub,
|
pubsub,
|
||||||
@@ -81,25 +65,24 @@ const server = new ApolloServer({
|
|||||||
req && req.headers.authorization
|
req && req.headers.authorization
|
||||||
? getUserId(req)
|
? getUserId(req)
|
||||||
: null
|
: null
|
||||||
|
}),
|
||||||
|
subscriptions: {
|
||||||
|
onConnect: (connectionParams) => {
|
||||||
|
if (connectionParams.authToken) {
|
||||||
|
return {
|
||||||
|
mongoose,
|
||||||
|
userId: getUserId(
|
||||||
|
null,
|
||||||
|
connectionParams.authToken
|
||||||
|
)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
mongoose
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// subscriptions: {
|
|
||||||
// onConnect: (connectionParams) => {
|
|
||||||
// if (connectionParams.authToken) {
|
|
||||||
// return {
|
|
||||||
// mongoose,
|
|
||||||
// userId: getUserId(
|
|
||||||
// null,
|
|
||||||
// connectionParams.authToken
|
|
||||||
// )
|
|
||||||
// };
|
|
||||||
// } else {
|
|
||||||
// return {
|
|
||||||
// mongoose
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
introspection: true,
|
introspection: true,
|
||||||
tracing: true,
|
tracing: true,
|
||||||
path: '/',
|
path: '/',
|
||||||
@@ -121,39 +104,5 @@ server.applyMiddleware({
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.listen({ port: process.env.PORT }, () => {
|
app.listen({ port: process.env.PORT }, () => {
|
||||||
console.log(`🚀 Server listening on port ${process.env.PORT}`);
|
console.log(`Server listening on port ${process.env.PORT}`);
|
||||||
console.log(`😷 Health checks available at ${process.env.HEALTH_ENDPOINT}`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// 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');
|
|
||||||
// const Mutation = require('./resolvers/Mutation');
|
|
||||||
// const Subscription = require('./resolvers/Subscription');
|
|
||||||
// const User = require('./resolvers/User');
|
|
||||||
// const Appointment = require('./resolvers/Appointment');
|
|
||||||
// const Follow = require('./resolvers/Follow');
|
|
||||||
// const fs = require('fs');
|
|
||||||
// const path = require('path');
|
|
||||||
// const { getUserId } = require('./utils');
|
|
||||||
|
|
||||||
// const graphqlResolvers = {
|
|
||||||
// appointmentResolvers,
|
|
||||||
// userResolvers
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // const resolvers = {
|
|
||||||
// // Query,
|
|
||||||
// // Mutation,
|
|
||||||
// // Subscription,
|
|
||||||
// // User,
|
|
||||||
// // Appointment,
|
|
||||||
// // Follow
|
|
||||||
// // };
|
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ const AppointmentSchema = new Schema({
|
|||||||
deleted: {
|
deleted: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false
|
required: false
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: "user",
|
||||||
|
required: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
export default mongoose.model('appointment', AppointmentSchema);
|
export default mongoose.model('appointment', AppointmentSchema);
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import mongoose from 'mongoose';
|
|
||||||
const Schema = mongoose.Schema;
|
|
||||||
const ProductSchema = new Schema({
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
qty: {
|
|
||||||
type: Number
|
|
||||||
}
|
|
||||||
});
|
|
||||||
export default mongoose.model('product', ProductSchema);
|
|
||||||
@@ -1,33 +1,25 @@
|
|||||||
// import Appointment from '../../client/src/components/Appointment.js';
|
|
||||||
import Product from './models/product.js';
|
|
||||||
import Appointment from './models/appointment.js';
|
import Appointment from './models/appointment.js';
|
||||||
import User from './models/user.js'
|
import User from './models/user.js';
|
||||||
// import { createAppointment } from './resolvers/Mutation.js';
|
|
||||||
import bcrypt from 'bcrypt';
|
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import dotenv from 'dotenv';
|
import { createAppointment } from './resolvers/Mutation';
|
||||||
|
|
||||||
export const resolvers = {
|
export const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
async allAppointments() {
|
async allAppointments() {
|
||||||
return await Appointment.find({ deleted: false })
|
return await Appointment.find({ deleted: false });
|
||||||
// return await Appointment.find();
|
|
||||||
},
|
},
|
||||||
async oneAppointment(root, args, context, info) {
|
async oneAppointment(root, args) {
|
||||||
return await Appointment.findOne({
|
return await Appointment.findOne({
|
||||||
_id: args._id
|
_id: args._id
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async allProducts() {
|
|
||||||
return await Product.find();
|
|
||||||
},
|
|
||||||
async allUsers() {
|
async allUsers() {
|
||||||
return await User.find();
|
return await User.find();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
async signup(root, args, context, info) {
|
async signup(root, args) {
|
||||||
var user = await User.create(args);
|
const user = await User.create(args);
|
||||||
user.password = user.generateHash(args.password);
|
user.password = user.generateHash(args.password);
|
||||||
user.save();
|
user.save();
|
||||||
|
|
||||||
@@ -39,11 +31,7 @@ export const resolvers = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
async login(parent, args, context, info) {
|
async login(parent, args) {
|
||||||
console.log(context);
|
|
||||||
const { userId } = context;
|
|
||||||
console.log(userId);
|
|
||||||
|
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
email: args.email
|
email: args.email
|
||||||
});
|
});
|
||||||
@@ -63,47 +51,15 @@ export const resolvers = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
async createAppointment(parent, args, context, info) {
|
async createAppointment(parent, args, context) {
|
||||||
console.log(context);
|
return await createAppointment(parent, args, context);
|
||||||
const { userId } = context;
|
|
||||||
console.log("userID", userId);
|
|
||||||
args.deleted = false;
|
|
||||||
args.createdBy = userId;
|
|
||||||
return await Appointment.create(args);
|
|
||||||
},
|
},
|
||||||
async updateAppointment(parent, args, context, info) {
|
async updateAppointment(parent, args) {
|
||||||
console.log(args);
|
|
||||||
return await Appointment.findOneAndUpdate({
|
return await Appointment.findOneAndUpdate({
|
||||||
args
|
args
|
||||||
}, args, {
|
}, args, {
|
||||||
new: true
|
new: true
|
||||||
})
|
|
||||||
},
|
|
||||||
async deleteAppointment(parent, args, context, info) {
|
|
||||||
return await Appointment.findOneAndUpdate({ _id: args._id }, { deleted: true })
|
|
||||||
// return await Appointment.deleteOne({ _id: args._id });
|
|
||||||
},
|
|
||||||
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
|
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1,28 +1,25 @@
|
|||||||
const bcrypt = require('bcryptjs');
|
const bcrypt = require('bcryptjs');
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const { APP_SECRET } = require('../utils');
|
import dotenv from 'dotenv';
|
||||||
|
import appointment from '../models/appointment';
|
||||||
|
|
||||||
function createAppointment(parent, args, context, info) {
|
dotenv.config();
|
||||||
|
|
||||||
|
async function createAppointment(parent, args, context) {
|
||||||
const { userId } = context;
|
const { userId } = context;
|
||||||
|
args.deleted = false;
|
||||||
const newAppointment = context.mongo.appointment.create({
|
args.createdBy = userId;
|
||||||
data: {
|
console.log(parent, args, context);
|
||||||
title: args.title,
|
return await appointment.create(args);
|
||||||
description: args.description,
|
|
||||||
createdBy: { connect: { id: userId } }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return newAppointment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function signup(parent, args, context, info) {
|
async function signup(parent, args, context) {
|
||||||
const password = await bcrypt.hash(args.password, 10);
|
const password = await bcrypt.hash(args.password, 10);
|
||||||
const user = await context.mongo.user.create({
|
const user = await context.mongo.user.create({
|
||||||
data: { ...args, password }
|
data: { ...args, password }
|
||||||
});
|
});
|
||||||
|
|
||||||
const token = jwt.sign({ userId: user.id }, APP_SECRET);
|
const token = jwt.sign({ userId: user.id }, process.env.APP_SECRET);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
token,
|
token,
|
||||||
@@ -30,7 +27,7 @@ async function signup(parent, args, context, info) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function login(parent, args, context, info) {
|
async function login(parent, args, context) {
|
||||||
const user = await context.mongo.user.findUnique({
|
const user = await context.mongo.user.findUnique({
|
||||||
where: { email: args.email }
|
where: { email: args.email }
|
||||||
});
|
});
|
||||||
@@ -46,7 +43,7 @@ async function login(parent, args, context, info) {
|
|||||||
throw new Error('Invalid password');
|
throw new Error('Invalid password');
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = jwt.sign({ userId: user.id }, APP_SECRET);
|
const token = jwt.sign({ userId: user.id }, process.env.APP_SECRET);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
token,
|
token,
|
||||||
@@ -54,18 +51,18 @@ async function login(parent, args, context, info) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function follow(parent, args, context, info) {
|
async function follow(parent, args, context) {
|
||||||
const { userId } = context;
|
const { userId } = context;
|
||||||
const follow = await context.mongo.follow.findUnique({
|
const follow = await context.mongo.follow.findUnique({
|
||||||
where: {
|
where: {
|
||||||
linkId_userId: {
|
linkId_userId: {
|
||||||
linkId: Number(args.linkId),
|
linkId: Number(args.linkId),
|
||||||
userId: userId
|
userId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Boolean(follow)) {
|
if (follow) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Already followed the appointment: ${args.linkId}`
|
`Already followed the appointment: ${args.linkId}`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
async function feed(parent, args, context, info) {
|
async function feed(parent, args, context) {
|
||||||
|
|
||||||
const where = args.filter
|
const where = args.filter
|
||||||
? {
|
? {
|
||||||
|
|||||||
@@ -1,26 +1,22 @@
|
|||||||
function newLinkSubscribe(parent, args, context, info) {
|
function newAppointmentSubscribe(parent, args, context) {
|
||||||
return context.pubsub.asyncIterator("NEW_LINK")
|
return context.pubsub.asyncIterator("NEW_APPOINTMENT");
|
||||||
}
|
}
|
||||||
|
|
||||||
const newAppointment = {
|
const newAppointment = {
|
||||||
subscribe: newLinkSubscribe,
|
subscribe: newAppointmentSubscribe,
|
||||||
resolve: payload => {
|
resolve: payload => payload,
|
||||||
return payload
|
};
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
function newFollowSubscribe(parent, args, context, info) {
|
function newFollowSubscribe(parent, args, context) {
|
||||||
return context.pubsub.asyncIterator("NEW_FOLLOW")
|
return context.pubsub.asyncIterator("NEW_FOLLOW");
|
||||||
}
|
}
|
||||||
|
|
||||||
const newFollow = {
|
const newFollow = {
|
||||||
subscribe: newFollowSubscribe,
|
subscribe: newFollowSubscribe,
|
||||||
resolve: payload => {
|
resolve: payload => payload,
|
||||||
return payload
|
};
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
newAppointment,
|
newAppointment,
|
||||||
newFollow
|
newFollow
|
||||||
}
|
};
|
||||||
@@ -6,11 +6,8 @@ type Query {
|
|||||||
take: Int
|
take: Int
|
||||||
orderBy: AppointmentOrderByInput
|
orderBy: AppointmentOrderByInput
|
||||||
): Feed!
|
): Feed!
|
||||||
allProducts: [Product]
|
|
||||||
allAppointments: [Appointment]
|
allAppointments: [Appointment]
|
||||||
oneAppointment(
|
oneAppointment(_id: ID!): Appointment
|
||||||
_id: ID!
|
|
||||||
): Appointment
|
|
||||||
allUsers: [User]
|
allUsers: [User]
|
||||||
users: [User!]!
|
users: [User!]!
|
||||||
}
|
}
|
||||||
@@ -31,7 +28,7 @@ type Mutation {
|
|||||||
deleted: Boolean
|
deleted: Boolean
|
||||||
): Appointment!
|
): Appointment!
|
||||||
updateAppointment(
|
updateAppointment(
|
||||||
_id: ID!,
|
_id: ID!
|
||||||
title: String!
|
title: String!
|
||||||
description: String
|
description: String
|
||||||
type: String!
|
type: String!
|
||||||
@@ -39,31 +36,10 @@ type Mutation {
|
|||||||
end: DateTime!
|
end: DateTime!
|
||||||
deleted: Boolean
|
deleted: Boolean
|
||||||
): Appointment
|
): Appointment
|
||||||
deleteAppointment(
|
deleteAppointment(_id: ID!): Appointment
|
||||||
_id: ID!
|
signup(email: String!, password: String!, username: String!): AuthPayload
|
||||||
) : Appointment
|
login(email: String!, password: String!): AuthPayload
|
||||||
createProduct(
|
follow(appointmentId: ID!): Follow
|
||||||
input: ProductInput
|
|
||||||
) : Product
|
|
||||||
updateProduct(
|
|
||||||
_id: ID!,
|
|
||||||
input: ProductInput
|
|
||||||
): Product
|
|
||||||
deleteProduct(
|
|
||||||
_id: ID!
|
|
||||||
) : Product
|
|
||||||
signup(
|
|
||||||
email: String!
|
|
||||||
password: String!
|
|
||||||
username: String!
|
|
||||||
): AuthPayload
|
|
||||||
login(
|
|
||||||
email: String!,
|
|
||||||
password: String!
|
|
||||||
): AuthPayload
|
|
||||||
follow(
|
|
||||||
appointmentId: ID!
|
|
||||||
): Follow
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Subscription {
|
type Subscription {
|
||||||
@@ -77,13 +53,13 @@ type User {
|
|||||||
username: String!
|
username: String!
|
||||||
email: String!
|
email: String!
|
||||||
password: String!
|
password: String!
|
||||||
# appointments: [Appointment!]!
|
appointments: [Appointment!]!
|
||||||
}
|
}
|
||||||
input UserInput {
|
input UserInput {
|
||||||
username: String!
|
username: String!
|
||||||
email: String!
|
email: String!
|
||||||
password: String!
|
password: String!
|
||||||
# appointments: [Appointment!]!
|
appointments: [AppointmentInput!]!
|
||||||
}
|
}
|
||||||
type AuthPayload {
|
type AuthPayload {
|
||||||
token: String
|
token: String
|
||||||
@@ -101,7 +77,6 @@ type Appointment {
|
|||||||
deleted: Boolean
|
deleted: Boolean
|
||||||
createdBy: User
|
createdBy: User
|
||||||
# follows: [Follow!]!
|
# follows: [Follow!]!
|
||||||
# createdAt: DateTime!
|
|
||||||
}
|
}
|
||||||
input AppointmentInput {
|
input AppointmentInput {
|
||||||
title: String!
|
title: String!
|
||||||
@@ -114,18 +89,6 @@ input AppointmentInput {
|
|||||||
input AppointmentOrderByInput {
|
input AppointmentOrderByInput {
|
||||||
title: Sort
|
title: Sort
|
||||||
desc: Sort
|
desc: Sort
|
||||||
# createdAt: Sort
|
|
||||||
}
|
|
||||||
|
|
||||||
# Product schemas
|
|
||||||
type Product {
|
|
||||||
_id: ID!
|
|
||||||
title: String!
|
|
||||||
qty: Int
|
|
||||||
}
|
|
||||||
input ProductInput {
|
|
||||||
title: String!
|
|
||||||
qty: Int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Follow schemas
|
# Follow schemas
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
const APP_SECRET = 'GraphQL-is-aw3some';
|
import dotenv from 'dotenv';
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
function getTokenPayload(token) {
|
function getTokenPayload(token) {
|
||||||
return jwt.verify(token, APP_SECRET);
|
return jwt.verify(token, process.env.APP_SECRET);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserId(req, authToken) {
|
function getUserId(req, authToken) {
|
||||||
@@ -25,6 +27,5 @@ function getUserId(req, authToken) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
APP_SECRET,
|
|
||||||
getUserId
|
getUserId
|
||||||
};
|
};
|
||||||
|
|||||||
12264
server/yarn.lock
12264
server/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user