├── .circleci └── config.yml ├── .gitignore ├── README.md ├── _config.yml ├── doc ├── build_a_schema.md ├── connect_client_api.md ├── fetch_data_with_queries.md ├── get_started.md ├── graph_resolvers.md ├── hook_up_datasource.md ├── img │ ├── console.png │ ├── graphQL.png │ └── spacex.png ├── manage_local_state.md └── update_data_with_mutations.md ├── final ├── client │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── apollo.config.js │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── manifest.json │ ├── src │ │ ├── assets │ │ │ ├── curve.svg │ │ │ ├── icons │ │ │ │ ├── cart.svg │ │ │ │ ├── exit.svg │ │ │ │ ├── home.svg │ │ │ │ └── profile.svg │ │ │ ├── images │ │ │ │ ├── badge-1.png │ │ │ │ ├── badge-2.png │ │ │ │ ├── badge-3.png │ │ │ │ ├── dog-1.png │ │ │ │ ├── dog-2.png │ │ │ │ ├── dog-3.png │ │ │ │ ├── galaxy.jpg │ │ │ │ ├── iss.jpg │ │ │ │ ├── moon.jpg │ │ │ │ └── space.jpg │ │ │ ├── logo.svg │ │ │ └── rocket.svg │ │ ├── components │ │ │ ├── __tests__ │ │ │ │ ├── button.js │ │ │ │ ├── footer.js │ │ │ │ ├── header.js │ │ │ │ ├── launch-detail.js │ │ │ │ ├── launch-tile.js │ │ │ │ ├── loading.js │ │ │ │ ├── login-form.js │ │ │ │ ├── menu-item.js │ │ │ │ └── page-container.js │ │ │ ├── button.js │ │ │ ├── footer.js │ │ │ ├── header.js │ │ │ ├── index.js │ │ │ ├── launch-detail.js │ │ │ ├── launch-tile.js │ │ │ ├── loading.js │ │ │ ├── login-form.js │ │ │ ├── menu-item.js │ │ │ └── page-container.js │ │ ├── containers │ │ │ ├── __tests__ │ │ │ │ ├── action-button.js │ │ │ │ ├── book-trips.js │ │ │ │ ├── cart-item.js │ │ │ │ └── logout-button.js │ │ │ ├── action-button.js │ │ │ ├── book-trips.js │ │ │ ├── cart-item.js │ │ │ ├── index.js │ │ │ └── logout-button.js │ │ ├── index.js │ │ ├── pages │ │ │ ├── __tests__ │ │ │ │ ├── cart.js │ │ │ │ ├── launch.js │ │ │ │ ├── launches.js │ │ │ │ ├── login.js │ │ │ │ └── profile.js │ │ │ ├── cart.js │ │ │ ├── index.js │ │ │ ├── launch.js │ │ │ ├── launches.js │ │ │ ├── login.js │ │ │ └── profile.js │ │ ├── resolvers.js │ │ ├── styles.js │ │ └── test-utils.js │ └── yarn.lock └── server │ ├── .env.example │ ├── apollo.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ ├── e2e.js.snap │ │ │ └── integration.js.snap │ │ ├── __utils.js │ │ ├── e2e.js │ │ ├── integration.js │ │ ├── resolvers.mission.js │ │ ├── resolvers.mutation.js │ │ ├── resolvers.query.js │ │ └── resolvers.user.js │ ├── common │ │ └── consts.js │ ├── datasources │ │ ├── __tests__ │ │ │ ├── launch.js │ │ │ └── user.js │ │ ├── launch.js │ │ └── user.js │ ├── index.js │ ├── resolvers.js │ ├── schema.js │ └── utils.js │ └── store.sqlite ├── google0f9167d144dd34a2.html ├── package-lock.json └── start ├── client ├── .env.example ├── .gitignore ├── README.md ├── apollo.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json ├── src │ ├── assets │ │ ├── curve.svg │ │ ├── icons │ │ │ ├── cart.svg │ │ │ ├── exit.svg │ │ │ ├── home.svg │ │ │ └── profile.svg │ │ ├── images │ │ │ ├── badge-1.png │ │ │ ├── badge-2.png │ │ │ ├── badge-3.png │ │ │ ├── dog-1.png │ │ │ ├── dog-2.png │ │ │ ├── dog-3.png │ │ │ ├── galaxy.jpg │ │ │ ├── iss.jpg │ │ │ ├── moon.jpg │ │ │ └── space.jpg │ │ ├── logo.svg │ │ └── rocket.svg │ ├── components │ │ ├── __tests__ │ │ │ ├── button.js │ │ │ ├── footer.js │ │ │ ├── header.js │ │ │ ├── launch-detail.js │ │ │ ├── launch-tile.js │ │ │ ├── loading.js │ │ │ ├── login-form.js │ │ │ ├── menu-item.js │ │ │ └── page-container.js │ │ ├── button.js │ │ ├── footer.js │ │ ├── header.js │ │ ├── index.js │ │ ├── launch-detail.js │ │ ├── launch-tile.js │ │ ├── loading.js │ │ ├── login-form.js │ │ ├── menu-item.js │ │ └── page-container.js │ ├── containers │ │ ├── __tests__ │ │ │ ├── action-button.js │ │ │ ├── book-trips.js │ │ │ ├── cart-item.js │ │ │ └── logout-button.js │ │ ├── action-button.js │ │ ├── book-trips.js │ │ ├── cart-item.js │ │ ├── index.js │ │ └── logout-button.js │ ├── index.js │ ├── pages │ │ ├── __tests__ │ │ │ ├── cart.js │ │ │ ├── launch.js │ │ │ ├── launches.js │ │ │ ├── login.js │ │ │ └── profile.js │ │ ├── cart.js │ │ ├── index.js │ │ ├── launch.js │ │ ├── launches.js │ │ ├── login.js │ │ └── profile.js │ ├── resolvers.js │ ├── styles.js │ └── test-utils.js └── yarn.lock └── server ├── .env.example ├── package-lock.json ├── package.json ├── src ├── __tests__ │ ├── __snapshots__ │ │ ├── e2e.js.snap │ │ └── integration.js.snap │ ├── __utils.js │ ├── e2e.js │ ├── integration.js │ ├── resolvers.mission.js │ ├── resolvers.mutation.js │ ├── resolvers.query.js │ └── resolvers.user.js ├── datasources │ ├── __tests__ │ │ ├── launch.js │ │ └── user.js │ ├── launch.js │ └── user.js ├── index.js ├── resolvers.js ├── schema.js └── utils.js └── store.sqlite /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 3 2 | 3 | jobs: 4 | Apollo Client: 5 | docker: 6 | - image: circleci/node:8 7 | 8 | steps: 9 | - checkout 10 | - run: cd final/client && npm ci 11 | - run: cd final/client && npm test 12 | - run: cd final/client && npx apollo client:check 13 | 14 | - run: | 15 | if [ "${CIRCLE_BRANCH}" == "master" ]; then 16 | cd final/client && npx apollo client:push 17 | fi 18 | 19 | Apollo Server: 20 | docker: 21 | - image: circleci/node:8 22 | 23 | steps: 24 | - checkout 25 | - run: cd final/server && npm ci 26 | - run: cd final/server && npm test 27 | 28 | - run: 29 | name: Starting server 30 | command: cd final/server && npm run start:ci 31 | background: true 32 | 33 | - run: sleep 5 34 | - run: cd final/server && npx apollo service:check 35 | 36 | - run: | 37 | if [ "${CIRCLE_BRANCH}" == "master" ]; then 38 | cd final/server && npx apollo service:push 39 | fi 40 | 41 | workflows: 42 | version: 3 43 | Build and Test: 44 | jobs: 45 | - Apollo Client 46 | - Apollo Server 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .history 2 | node_modules/ 3 | .DS_Store 4 | .env 5 | .vscode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 全栈学习教程 2 | 3 | Copyright (c) 2019 Gyges Zean 4 | 5 | This repository, free of charge, to any person obtaining a copy. 6 | 7 | `你有使用,拷贝,修改,合并,发布,分发,订阅或者把它卖出去的权力。任何你想到的你都可以去做。` 8 | 9 | `不过不要触犯法律。` 10 | 11 | ## 教程文档 12 | 13 | - [开始](./doc/get_started.md) 14 | - [构建schema](./doc/build_a_schema.md) 15 | - [连接数据源](./doc/hook_up_datasource.md) 16 | - [编写解析器](./doc/graph_resolvers.md) 17 | - [连接你的API到客户端](./doc/connect_client_api.md) 18 | - [获取查询数据](./doc/fetch_data_with_queries.md) 19 | - [通过mutations更新数据](./doc/update_data_with_mutations.md) 20 | - [管理本地状态](./doc/manage_local_state.md) 21 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /doc/connect_client_api.md: -------------------------------------------------------------------------------- 1 | - [主页](../README.md) 2 | 3 | # 连接你的API到客户端 4 | ## 把你的Graph连接到Apollo客户端 5 | 6 | 本章你会学到,如何使用React.js写的web客户端连接到后端服务,调用API。你还将了解如何构建身份验证和分页等基本功能,以及优化工作流的技巧。 7 | 8 | ## 建立好你的开发环境 9 | 10 | 此时在你的根目录下,在terminal里cd 进入client/目录下。 11 | 12 | ```shell 13 | cd start/client && npm install 14 | ``` 15 | 16 | 下面我介绍一下,我们前端package.json引入的一些依赖: 17 | 18 | `apollo-clinet`: 一个完全智能的数据缓存管理解决方案,我们将使用Apollo Client 3.0,它包含本地状态管理功能。你可以配置管理你的缓存。 19 | `react-apollo`: 用于`Query`和`Mutation`与view层集成的组件 20 | `graphql-tag`: 标记函数gql,我们使用它来包装查询字符串,为了将它们解析为AST 21 | 22 | 23 | 接下来,让我们配置一下Apollo, 创建一个`apollo.config.js`的文件,并粘贴下列代码进去. 24 | 这个文件主要是配置web应用名和服务名 25 | 26 | ```javascript 27 | module.exports = { 28 | client: { 29 | name: 'Space Explorer [web]', 30 | service: 'space-explorer', 31 | }, 32 | }; 33 | ``` 34 | 35 | ## 创建一个Apollo Client 36 | 37 | 现在我们已经安装了必要的包,让我们创建一个ApolloClient实例。 38 | 39 | 定位到`src/index.js`, 让我们来配置我们的URL,此URL就是指向后端服务的URL。 40 | 41 | ***src/index.js*** 42 | ```javascript 43 | import { ApolloClient } from 'apollo-client'; 44 | import { InMemoryCache } from 'apollo-cache-inmemory'; 45 | import { HttpLink } from 'apollo-link-http'; 46 | 47 | const cache = new InMemoryCache(); 48 | const link = new HttpLink({ 49 | uri: 'http://localhost:4000/' 50 | }); 51 | 52 | const client = new ApolloClient({ 53 | cache, 54 | link 55 | }); 56 | ``` 57 | 仅仅需要几行代码,我们的客户端就可以获取数据了。😄🎉🎉🎉🎉🧨🧨🧨 58 | 59 | ## 创建第一个查询 60 | 61 | 在向你展示如何使用Apollo的React集成之前,让我们先用普通的JavaScript发送一个查询。 62 | 63 | 使用`client.query()`来调用并查询graph的API。首先引入下列代码 64 | ```javascript 65 | import gql from "graphql-tag"; 66 | ``` 67 | 68 | 并将下面的代码添加到index.js的底部 69 | 70 | ```javascript 71 | // ... above is the instantiation of the client object. 72 | client 73 | .query({ 74 | query: gql` 75 | query GetLaunch { 76 | launch(id: 56) { 77 | id 78 | mission { 79 | name 80 | } 81 | } 82 | } 83 | ` 84 | }) 85 | .then(result => console.log(result)); 86 | ``` 87 | 88 | 使用`npm start`将你的前端应用启动起来,打开浏览器,输入地址`http://localhost:3000/`, 打开开发者工具 89 | 在console里就可以看到你调用的graph API的数据。Apollo Client 提供了原生的JavaScript的调用方式。但如果用框架的话,这样的调用会更方便。 90 | 91 | ![consolelog](./img/console.png) 92 | 93 | ## 如何集成GraphQL到react里 94 | 95 | 要将Apollo客户端连接到React,我们将把我们的应用程序包装在从`@ apollo / react-hooks`包导出的`ApolloProvider`组件中,并将client传递到`client` prop。 `ApolloProvider`组件类似于React的上下文提供程序。 它包装了你的React应用程序并将客户端放在上下文中,这使你可以从组件树中的任何位置访问它。 96 | 97 | 打开`src / index.js`并添加以下代码行: 98 | ***src/index.js*** 99 | 100 | ```javascript 101 | 102 | import { ApolloProvider } from '@apollo/react-hooks'; 103 | import React from 'react'; 104 | import ReactDOM from 'react-dom'; 105 | import Pages from './pages'; 106 | 107 | // previous variable declarations 108 | 109 | ReactDOM.render( 110 | 111 | 112 | , document.getElementById('root') 113 | ); 114 | 115 | ``` 116 | OK, 现在我们准备使用`userQuery` Hook来创建我们第一个组件。 117 | 118 | - [上一页](./graph_resolvers.md) [下一页](./fetch_data_with_queries.md) -------------------------------------------------------------------------------- /doc/get_started.md: -------------------------------------------------------------------------------- 1 | 2 | - [主页](../README.md) 3 | 4 | ## 说在前面 5 | ### 从这里开始学习如何构建全栈应用 6 | 7 | 欢迎各位,你可以通过这个教程指南学习如何使用强大的GraphQL构建全栈应用,废话不多说,直接进入主题。 8 | 9 | ### 我们将构建什么 10 | 11 | 一款为SpaceX飞船发射预定座位的软件 12 | 13 | 像下面这样: 14 | 15 | 16 | ![Image](./img/spacex.png) 17 | 18 | 这个应用包含: 19 | 20 | - 登陆页 21 | - 即将发布的清单 22 | - 发射平台的细节景观 23 | - 用户的主页信息 24 | - 购物车 25 | 26 | 为了实现这些功能,我们需要连接两个数据源,REST API和SQLite 数据库。不过不用担心,你无需了解这两种技术细节。 27 | 28 | 还必须提到的是,为了构建真正符合规范的应用,我们还必须用到身份验证,分页,以及状态管理。 29 | 30 | ### 先决条件 31 | 本教程需要你熟悉 `JavaScript/ES6` 和 `React`, 如果你要复习一下, Click it [🔗](https://reactjs.org/tutorial/tutorial.html), 还有,你可以学习一下GraphQL [😄Click me](https://graphql.org/learn/queries/) 32 | 33 | #### 系统环境要求 34 | - Node.js v8.x or later 35 | - npm v6.x or later 36 | - git v2.14.1 or later 37 | 38 | 同样也建议你使用 [VS Code](https://code.visualstudio.com/) 编辑器来写代码。以便使用apollo的插件 39 | 40 | #### 克隆APP例子 41 | 42 | 克隆这个仓库: 43 | 44 | ```shell 45 | git clone https://github.com/GZ315200/fullstack_tutorial.git 46 | ``` 47 | 48 | 克隆成功后,你可以看到两个文件,final 和 start, final是最终的代码,start是用来练习这个教程的demo,他们分别下面有两个文件,一个是client,另一个是server,server端构建graph API用到的。 49 | client端是用来浏览器访问的静态页面 50 | 51 | `不废话了,开始我们下一章节吧` 52 | 53 | - [下一页](./build_a_schema.md) -------------------------------------------------------------------------------- /doc/img/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/doc/img/console.png -------------------------------------------------------------------------------- /doc/img/graphQL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/doc/img/graphQL.png -------------------------------------------------------------------------------- /doc/img/spacex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/doc/img/spacex.png -------------------------------------------------------------------------------- /doc/update_data_with_mutations.md: -------------------------------------------------------------------------------- 1 | - [主页](../README.md) 2 | 3 | # 使用mutations更新数据 4 | ## 学习如何使用useMutation hook更新数据 5 | 6 | 接下来我们将学习如何使用useMutation hook来进行用户的登陆 7 | 8 | 9 | ## 什么是useMutation hook 10 | 11 | useMutation hook和useQuery一样都是来自@apollo/react-hooks。主要不同的是useMutation是用来更改数据 12 | 13 | ## 使用useMutation更新数据 14 | 15 | 第一步构建我们的GraphQL mutation。让我们导航到`src/pages/login.js`,并copy下列代码 16 | 17 | ***src/pages/login.js*** 18 | 19 | ```javascript 20 | import React from 'react'; 21 | import { useApolloClient, useMutation } from '@apollo/react-hooks'; 22 | import gql from 'graphql-tag'; 23 | 24 | import { LoginForm, Loading } from '../components'; 25 | 26 | const LOGIN_USER = gql` 27 | mutation login($email: String!) { 28 | login(email: $email) 29 | } 30 | `; 31 | ``` 32 | 33 | 接着让我们使用useMutation hook更新数据 34 | 35 | ***src/pages/login.js*** 36 | ```javascript 37 | export default function Login() { 38 | const [login, { data }] = useMutation(LOGIN_USER); 39 | return ; 40 | } 41 | ``` 42 | 43 | 为了给我们的用户创造更好的体验,我们希望在会话之间保持登录状态。 为此,我们需要将登录令牌保存到localStorage。 让我们学习如何使用useMutation的onCompleted处理程序来保持登录状态: 44 | 45 | ### 用useApolloClient暴露Apollo Client 46 | 47 | useApolloClient Hook 可以帮助我们访问客户端。 48 | 首先,让我们调用useApolloClient来获取当前已配置的客户端实例。接下来,我们像通过一个onCompleted的回调useMutation,同样我们在该回调里保存登陆token在localStorage里 49 | 我们在此次调用中也会使用到client.writeData方法将本地数据写入Apollo缓存中,用于标示用户已经登陆了。OK,来看看例子吧: 50 | 51 | ***src/pages/login.js*** 52 | 53 | ```javascript 54 | export default function Login() { 55 | 56 | const client = useApolloClient(); 57 | const [login, { loading, error }] = useMutation( 58 | LOGIN_USER, 59 | { 60 | onCompleted({ login }) { 61 | localStorage.setItem('token', login.token); 62 | client.writeData({ data: { isLoggedIn: true } }); 63 | } 64 | } 65 | ); 66 | 67 | if (loading) return ; 68 | if (error) return

An error occurred

; 69 | 70 | return ; 71 | } 72 | 73 | ``` 74 | 75 | ### 粘贴token信息到authorization报头去请求信息 76 | 77 | 我们将token信息粘贴带authorization报头内,然后请求后端数据。 78 | 我们将下列代码粘贴到src/index.js内,并替换之前对的client实例化方式,增加携带报头 79 | authorization的请求方式 80 | 81 | ***src/index.js*** 82 | 83 | ```javascript 84 | const client = new ApolloClient({ 85 | cache, 86 | link: new HttpLink({ 87 | uri: 'http://localhost:4000/graphql', 88 | 89 | headers: { 90 | authorization: localStorage.getItem('token'), 91 | }, 92 | }), 93 | }); 94 | 95 | cache.writeData({ 96 | data: { 97 | isLoggedIn: !!localStorage.getItem('token'), 98 | cartItems: [], 99 | }, 100 | }); 101 | ``` 102 | 103 | 指定headers项,并增加localStorage来保存token信息。 104 | 105 | 106 | 107 | 108 | - [上一页](./fetch_data_with_queries.md) [下一页](./manage_local_state.md) 109 | -------------------------------------------------------------------------------- /final/client/.env.example: -------------------------------------------------------------------------------- 1 | ENGINE_API_KEY= -------------------------------------------------------------------------------- /final/client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /final/client/README.md: -------------------------------------------------------------------------------- 1 | # Apollo Fullstack Tutorial 2 | 3 | ## Client 4 | -------------------------------------------------------------------------------- /final/client/apollo.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: { 3 | name: 'Space Explorer [web]', 4 | service: 'space-explorer', 5 | } 6 | } -------------------------------------------------------------------------------- /final/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@apollo/react-hooks": "3.0.0", 7 | "@reach/router": "^1.2.1", 8 | "apollo-cache-inmemory": "^1.6.2", 9 | "apollo-client": "^2.6.3", 10 | "apollo-link-http": "^1.5.15", 11 | "emotion": "^9.2.12", 12 | "graphql": "^14.4.2", 13 | "graphql-tag": "^2.10.1", 14 | "polished": "^3.4.1", 15 | "react": "^16.9.0-alpha.0", 16 | "react-dom": "^16.9.0-alpha.0", 17 | "react-emotion": "^9.2.12", 18 | "react-scripts": "3.0.1" 19 | }, 20 | "scripts": { 21 | "start": "react-scripts start", 22 | "build": "react-scripts build", 23 | "test": "react-scripts test", 24 | "eject": "react-scripts eject" 25 | }, 26 | "eslintConfig": { 27 | "extends": "react-app" 28 | }, 29 | "browserslist": [ 30 | ">0.2%", 31 | "not dead", 32 | "not ie <= 11", 33 | "not op_mini all" 34 | ], 35 | "devDependencies": { 36 | "@apollo/react-testing": "3.0.0", 37 | "@testing-library/jest-dom": "^4.0.0", 38 | "@testing-library/react": "^8.0.7", 39 | "apollo": "^2.16.3" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /final/client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/public/favicon.ico -------------------------------------------------------------------------------- /final/client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 23 | Launches 24 | 25 | 26 | 27 | 28 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /final/client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Launches", 3 | "name": "Launches", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /final/client/src/assets/curve.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /final/client/src/assets/icons/cart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /final/client/src/assets/icons/exit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /final/client/src/assets/icons/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /final/client/src/assets/icons/profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /final/client/src/assets/images/badge-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/badge-1.png -------------------------------------------------------------------------------- /final/client/src/assets/images/badge-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/badge-2.png -------------------------------------------------------------------------------- /final/client/src/assets/images/badge-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/badge-3.png -------------------------------------------------------------------------------- /final/client/src/assets/images/dog-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/dog-1.png -------------------------------------------------------------------------------- /final/client/src/assets/images/dog-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/dog-2.png -------------------------------------------------------------------------------- /final/client/src/assets/images/dog-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/dog-3.png -------------------------------------------------------------------------------- /final/client/src/assets/images/galaxy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/galaxy.jpg -------------------------------------------------------------------------------- /final/client/src/assets/images/iss.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/iss.jpg -------------------------------------------------------------------------------- /final/client/src/assets/images/moon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/moon.jpg -------------------------------------------------------------------------------- /final/client/src/assets/images/space.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GZ315200/fullstack_tutorial/afed967a6e28c7968219f3399fa9783fad6e7e99/final/client/src/assets/images/space.jpg -------------------------------------------------------------------------------- /final/client/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /final/client/src/components/__tests__/button.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { render, cleanup } from '../../test-utils'; 4 | import Button from '../button'; 5 | 6 | describe('Button', () => { 7 | // automatically unmount and cleanup DOM after the test is finished. 8 | afterEach(cleanup); 9 | 10 | it('renders without error', () => { 11 | render(); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /final/client/src/components/__tests__/footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { renderApollo, cleanup } from '../../test-utils'; 4 | import Footer from '../footer'; 5 | 6 | describe('Footer', () => { 7 | // automatically unmount and cleanup DOM after the test is finished. 8 | afterEach(cleanup); 9 | 10 | it('renders without error', () => { 11 | renderApollo(