Skip to content

Commit

Permalink
Refactor GraphQL queries and mutations (#360)
Browse files Browse the repository at this point in the history
  • Loading branch information
koistya committed Aug 21, 2019
1 parent 3bad2f2 commit 1fc2636
Show file tree
Hide file tree
Showing 42 changed files with 820 additions and 625 deletions.
2 changes: 1 addition & 1 deletion .vscode/snippets/javascript.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
" ${1:Component},",
" {",
" data: graphql`",
" fragment ${1:Component} on Query {",
" fragment ${1:Component}_data on Query {",
" id",
" }",
" `,",
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,22 @@ Also, you need to be familiar with [HTML][html], [CSS][css], [JavaScript][js] ([
├── src/ # Application source code
│ ├── admin/ # Admin section (Dashboard, User Management etc.)
│ ├── common/ # Shared React components and HOCs
│ ├── hooks/ # React.js hooks and Context providers
│ ├── icons/ # Icon components
│ ├── legal/ # Terms of Use, Privacy Policy, etc.
│ ├── misc/ # Other pages (about us, contacts, etc.)
│ ├── mutations/ # GraphQL mutations to be used on the client
│ ├── news/ # News section (example)
│ ├── server/ # Server-side code (API, authentication, etc.)
│ │ ├── db/ # Database client
│ │ ├── story/ # Story related schema, queries, and mutations
│ │ ├── mutations/ # GraphQL mutations
│ │ ├── queries/ # The top-level GraphQL query fields
│ │ ├── story/ # GraphQL types: Story, Comment etc.
│ │ ├── templates/ # HTML templates for server-side rendering
│ │ ├── user/ # User related schema, queries, and mutations
│ │ ├── user/ # GraphQL types: User, UserRole, UserIdentity etc.
│ │ ├── api.js # GraphQL API middleware
│ │ ├── app.js # Express.js application
│ │ ├── config.js # Configuration settings to be passed to the client
│ │ ├── Context.js # GraphQL context wrapper
│ │ ├── createRelay.js # Relay factory method for Node.js environment
│ │ ├── index.js # Node.js app entry point
Expand All @@ -61,7 +67,6 @@ Also, you need to be familiar with [HTML][html], [CSS][css], [JavaScript][js] ([
│ ├── user/ # User pages (login, account settings, user profile, etc)
│ ├── utils/ # Utility functions
│ ├── createRelay.js # Relay factory method for browser envrironment
│ ├── hooks.js # React.js hooks and Context providers
│ ├── index.js # Client-side entry point, e.g. ReactDOM.render(<App />, container)
│ ├── router.js # Universal application router
│ ├── serviceWorker.js # Service worker helper methods
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@babel/polyfill": "^7.2.5",
"@babel/runtime": "^7.3.1",
"@firebase/app": "^0.4.14",
"@firebase/auth": "^0.11.8",
"@material-ui/core": "^4.3.2",
"@material-ui/icons": "^4.2.1",
"body-parser": "^1.19.0",
Expand Down Expand Up @@ -54,8 +55,8 @@
"relay-runtime": "^5.0.0",
"request": "^2.88.0",
"request-promise-native": "^1.0.7",
"serialize-javascript": "^1.7.0",
"slug": "^1.1.0",
"serialize-javascript": "^1.8.0",
"slugify": "^1.3.4",
"universal-router": "^8.2.1",
"uuid": "^3.3.3",
"validator": "^11.1.0"
Expand Down
54 changes: 21 additions & 33 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,6 @@ type Comment implements Node {
updatedAt(format: String): String
}

input CreateStoryInput {
title: String
text: String
validateOnly: Boolean
clientMutationId: String
}

type CreateStoryPayload {
story: Story
clientMutationId: String
}

input DeleteUserInput {
id: ID!
clientMutationId: String
Expand Down Expand Up @@ -61,16 +49,15 @@ type LikeStoryPayload {
}

type Mutation {
# Update user.
# Creates or updates a story.
upsertStory(input: UpsertStoryInput!): UpsertStoryPayload
likeStory(input: LikeStoryInput!): LikeStoryPayload

# Updates a user.
updateUser(input: UpdateUserInput!): UpdateUserPayload

# Delete user.
# Deletes a user.
deleteUser(input: DeleteUserInput!): DeleteUserPayload

# Create a new story.
createStory(input: CreateStoryInput!): CreateStoryPayload
updateStory(input: UpdateStoryInput!): UpdateStoryPayload
likeStory(input: LikeStoryInput!): LikeStoryPayload
}

# An object with an ID
Expand Down Expand Up @@ -129,20 +116,6 @@ type Story implements Node {
updatedAt(format: String): String
}

input UpdateStoryInput {
id: ID!
title: String
text: String
approved: Boolean
validateOnly: Boolean
clientMutationId: String
}

type UpdateStoryPayload {
story: Story
clientMutationId: String
}

input UpdateUserInput {
id: ID!
username: String
Expand All @@ -160,6 +133,20 @@ type UpdateUserPayload {
clientMutationId: String
}

input UpsertStoryInput {
id: ID
title: String
text: String
approved: Boolean
validateOnly: Boolean
clientMutationId: String
}

type UpsertStoryPayload {
story: Story
clientMutationId: String
}

type User implements Node {
# The ID of an object
id: ID!
Expand All @@ -170,6 +157,7 @@ type User implements Node {
timeZone: String
identities: [Identity]
isAdmin: Boolean
firebaseToken: String
createdAt(format: String): String
updatedAt(format: String): String
lastLoginAt(format: String): String
Expand Down
68 changes: 68 additions & 0 deletions src/common/TextField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* React Starter Kit for Firebase
* https://github.com/kriasoft/react-firebase-starter
* Copyright (c) 2015-present Kriasoft | MIT License
*/

import clsx from 'clsx';
import React from 'react';
import MuiTextField from '@material-ui/core/TextField';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles(theme => ({
root: {
marginBottom: theme.spacing(1),
},
maxLength: {
float: 'right',
},
}));

function TextField(props) {
const {
className,
name,
state: [state, setState],
maxLength,
required,
...other
} = props;

const s = useStyles();
const errors = (state.errors || {})[name] || [];
const error = errors.length ? errors.join(' \n') : null;
const hasError =
Boolean(error) || (maxLength && (state[name] || '').length > maxLength);

let helperText = error || (required ? '* Required' : ' ');

if (maxLength) {
helperText = (
<React.Fragment>
{helperText}
<span className={s.maxLength}>
{(state[name] || '').length}/{maxLength}
</span>
</React.Fragment>
);
}

function handleChange(event) {
const { name, value } = event.target;
setState(x => ({ ...x, [name]: value }));
}

return (
<MuiTextField
className={clsx(s.root, className)}
name={name}
error={hasError}
value={state[name]}
onChange={handleChange}
helperText={helperText}
{...other}
/>
);
}

export default TextField;
52 changes: 0 additions & 52 deletions src/common/withAuth.js

This file was deleted.

39 changes: 0 additions & 39 deletions src/hooks.js

This file was deleted.

12 changes: 12 additions & 0 deletions src/hooks/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* React Starter Kit for Firebase
* https://github.com/kriasoft/react-firebase-starter
* Copyright (c) 2015-present Kriasoft | MIT License
*/

export * from './useAuth';
export * from './useConfig';
export * from './useFirebase';
export * from './useHistory';
export * from './useRelay';
export * from './useReset';
42 changes: 42 additions & 0 deletions src/hooks/useAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* React Starter Kit for Firebase
* https://github.com/kriasoft/react-firebase-starter
* Copyright (c) 2015-present Kriasoft | MIT License
*/

import React from 'react';

import { useHistory } from './useHistory';
import { useReset } from './useReset';
import { openWindow } from '../utils';

export function useAuth() {
const history = useHistory();
const reset = useReset();

return React.useMemo(
() => ({
signIn(options = {}) {
return openWindow(options.url || '/login', {
onPostMessage({ data }) {
if (typeof data === 'string' && data === 'login:success') {
reset();
history.replace(history.location);
return Promise.resolve();
}
},
});
},

async signOut() {
await fetch('/login/clear', {
method: 'POST',
credentials: 'include',
});
reset();
history.push('/');
},
}),
[],
);
}
13 changes: 13 additions & 0 deletions src/hooks/useConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* React Starter Kit for Firebase
* https://github.com/kriasoft/react-firebase-starter
* Copyright (c) 2015-present Kriasoft | MIT License
*/

import React from 'react';

export const ConfigContext = React.createContext({});

export function useConfig() {
return React.useContext(ConfigContext);
}
Loading

0 comments on commit 1fc2636

Please sign in to comment.