/github-search

Github search app made with React, Redux, and GraphQL

Primary LanguageTypeScript

Build Status Netlify Status

Github search, modern web app

This small application allows searches using the Github v4 API (GraphQL), displays the user information and his repositories.

Stack: Typescript, React, GraphQL with Apollo Client and Redux, and Jest for tests.

✅ Live version: github-search-react.netlify.com

Roadmap:

  • Display search UI and results page with data fetched from Github API
  • Dynamic Themes (changes CSS theme on demand through UI option) using native CSS variables
  • Multilingual support (EN | BR | ES)
  • Fully responsive, without frameworks (using native flexbox CSS)
  • Progresive web app
  • Add CI service to run tests (Travis CI)
  • Use guides for accessibility (WAI-ARIA standard)
  • Use animations, page transitions, and elements
  • Store user settings on localStorage (to keep the settings even if the page refreshes)

Main future improvements

  • Add a significant amount of tests and improve the quality of existing tests (for now, only tests components mount with react-dom, react-router, and Jest)
  • Move all user settings to Redux store (lang, themes)
  • Use styled-components themes instead of native CSS variables
  • Write a Docker file to deploy in own servers (no netlify-like integrations)

Good practices

  • Use Eslint (code linter with support for Typescript)
  • Prettier (code formatting) with a Pre-Commit hook (git)
  • Semantic Commit Messages

Installation

Create .env file with your Github Token, this token is required by Github GraphQL API. (more information about token here)

REACT_APP_GITUHB_API_TOKEN=___YOUR_TOKEN_HERE___

After that, in the project directory, run:

npm install

this command will install all needed project dependencies

Available commands (after installation)

In the project directory, you can run:

npm start

Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.
You will also see any lint errors in the console.

npm test

Launches the test runner in the interactive watch mode.
See the section about running tests for more information.

npm run build

Builds the app for production to the build folder.
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.
Your app is ready to be deployed!

Project structure

This project was bootstrapped with Create React App, and the main structure is proposed by this boilerplate, also, as a component strategy use "atomic design pattern" where the main goal is divide into differents component as is possible, finding a balance between coupling and cohesion.

├── App.tsx
├── assets
├── common
│   ├── Logo
│   │   └── index.tsx
│   ├── Search
│   │   ├── Button.tsx
│   │   ├── Input.tsx
│   └── index.tsx
├── config.tsx
├── index.tsx
├── pages
│   ├── home
│   └── results
│       ├── components
│       │   ├── Avatar.tsx
│       │   ├── Info.tsx
│       │   ├── Result.tsx
│       │   ├── Sidebar.tsx
│       │   └── index.tsx
│       └── index.tsx
├── react-app-env.d.ts
├── serviceWorker.ts
└── styles
    └── index.scss

Each component folder contains a directory called __tests__ where test files are located with .test.tsx suffix.

Main directories are: common with shared components around de app. pages that contain two main pages components (home and results), each directory has a components folder with local comps. The main internal configuration is located on src/config.tsx where you can see some constants and static configuration. About the styles, the local CSS live in each component, but in the file styles/index.scssyou can found global CSS variables and html/fonts/global layout styles.

GraphQL approach

One of the main advantages of using GraphQL is the declarative way in how we write the queries to the server, for this example application, the query groups the user information and its repositories using the username, type and order parameters as variables (example: direction DESC on stars) (located on: src/pages/results/github-user.graphql)

query SearchReposByUser($login: String!, $queryString: String!, $pageSize: Int!) {
  search(query: $queryString, type: REPOSITORY, first: $pageSize) {
    edges {
      node {
        ... on Repository {
          name
          description
          url
          stargazers(orderBy: { field: STARRED_AT, direction: DESC }) {
            totalCount
          }
        }
      }
    }
  }
  user(login: $login) {
    name
    login
    organization(login: $login) {
      name
    }
    avatarUrl
    location
    starredRepositories {
      totalCount
    }
    repositories {
      totalCount
    }
    followers {
      totalCount
    }
  }
}

Architecture

Because the control of the local state in apollo client is still incipient, and when projects grow too much it becomes complex to manage the state of the application, this proposal includes the use of a redux store for internal state management, using all the advantages that this implies.

On the other hand using the advantages of GraphQL and the cache of apollo client in each query.

This configuration allows passing values from the Apollo store to redux, using a serializing layer that will keep the container component (data handler) agnostic of data fetching by means of a stateless component.

In the future, the challenge will be to keep the Apollo cache updated with the Redux store automatically.

  +---------------------+
  |     Apollo Client   |
  | +-----------------+ |
  | |                 | |
  | |      Redux      | |
  | |                 | |
  | +-----------------+ |
  |                     |
  +---------------------+

With this approach, you can use redux devs tools to interact with the application state, in this example, we see the user info and results as a graph.

alt text

Conventions

  • Semantic Commit Messages
  • Semantic versioning
  • Gitflow, as a git strategy
  • Changelog [Standard Version]

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

1.3.0 (2019-11-18)

Features

Bug Fixes

  • update translation ES

1.2.0 (2019-11-17)

Features

  • add :hover style over button (8b5623c)
  • add 'connected-react-router' to manage routes as value on redux store (d253fcf)
  • add basic redux implementation (d5c3d2b)
  • add graphql.macro to load .graphql files. This change adds best readability (76e7f5f)
  • add mapStateToProps to results page component (72475f3)
  • add UserInfo reducer and store data from fetch GraphQL Hook (3d0c300)
  • display data from redux store, remove values directly from graphql query component (0576679)
  • improve components file structure (a1cab67)
  • improve Redux implementation. Add data from GraphQL fetch Hook (bd752c7)

Bug Fixes

  • set right current lang value (65e9f34)

1.1.2 (2019-11-14)

1.0.1 (2019-11-13)