Contributors Forks Stargazers Issues MIT License LinkedIn


Logo

theSwattr - Client

React, Node.js, Postgresql
Explore the docs »

Report Bug · Request Feature?


Bug Tracker App

Click the title to go to the live app!

Demo Credentials:

Username: admin
Password: pass

This README will systematically go over the entire app from the top level to the bottom layer, so I'll provide links to various sections for convenience.

TODO - ADD DIRECTORY LINKS!


What's this app for!?

This app is for tracking bugs in your app, offering an API for both users and developers to submit bugs and then follow-up with a kind of message board on a bug-by-bug basis. I'll quickly go over the basic functions of the client - with pictures!

Main Dashboard for devs...
erm
...and for users.
erm
  • The main take-away here is that devs can see all bugs, while regular users can only see bugs they submitted themselves. That's the basic for the difference between user and developer views throughout the app.
Clicking on the Toggle Dev button will take you to...
Toggle Dev Page
erm
  • Here you can see your current dev status, and enter a secret to toggle it on (or off!). The current secret code is irdev
Clicking on a bug will take you to...
Comments Page
erm
  • Here you can view all comments for the selected bug ordered by date, and create a new comment when desired.
Clicking Add Bug takes you to...
Add Bug Page
erm
  • Here you can add a new bug, with a default status and severity set to pending, later to be updated by a dev.
Lastly, as a dev, there's an extra button above the comments when viewing a bug. Clicking the Edit Bug button leads to...
Edit Bug Page
erm
  • Devs can set status and severity here, along with some other parameters if the bug was submitted incorrectly.

public

The Public folder is nothing special, besides the custom favicon and (as I'll note later) some imported CDNs in the head of index.html for a few Google Fonts.

As an aside, it's actually faster (from a runtime perspective) to import fonts via CDNs, as apposed to importing them directly into stylesheets


src:

config.js, index.js, and setupTests.js

[ config.js ] - this is essentially where I store "environment" variables. One important thing to know is that React has a built-in NODE_ENV variable that is set automatically when running scripts:

  1. Run Start: NODE_ENV = developement
  2. Run Build: NODE_ENV = production

    Knowing this, you can take advantage and set up conditionals based on the already-available NODE_ENV. A major advantage is setting up API urls. When exporting like this...

    export default { ...config };

    ... you can access variables like this...

    import config from '.../config.js';
    ...
      await fetch(config.API_ENDPOINT)

    [ index.js ] - bog-standard React App-wrapper using BrowserRouter [ setupTests.js ] - configuration for Enzyme testing


styles:

Fairly straight-forward Sass setup, with a simple reset and global stylesheet imported into the root index file. I won't get into Sass here, but know that I broke-out individual mixins to be used as imports in isolated [ .scss ] files


I'll briefly cover some global-level stuff before breaking down the App itself

jsconfig.json:

This is at the root level, but it's use is important in understanding the syntax used throughout the app. I won't go too in-depth, but essentially what's going on is it's creating a global alias for the [ src/ ] file directory. The side effect is that you can re-factor local imports:

/* deeplyNestedComponent.js */
import { PostService } from '../../../../../src/services';
...to...
import { PostService } from 'src/services';

For more info on the jsconfig.json, check out the docs HERE!

constants:

Not strictly necessary, but this can help prevent typos, along with making changes to the database less tedious to update throughout the app.

services:

This is where the logic for interfacing with the server lives. Each "method" has been broken-out into it's own file. [ token.service.js ] is for handling Auth-token processes.

One exception in the token.service.js file, where all the interfacing with window.localStorage is handled. The other is idle.service.js, which determins the JWT expiration and regularly refreshes the stored authToken.

hooks:

This is where I keep custom hooks used by multiple components, though only 1 was needed. This hook handles every form in the app, recieving and updating piped-in form-fields. The major benefit of this kind of hook is that it minimizes the use of useState hooks throughout the app and normalizes form handling.

TODO!!!

context:

This is the "hook" way of doing context, both creating the context...

export const DatabaseContext = createContext();

...and provider...

<DatabaseContext.Provider value={value}>
  {props.children}
</DatabaseContext.Provider>

...in the same file. To use, you import the provider at the top level...

import DatabaseContextProvider from '.../databaseContext';
...
<DatabaseContextProvider>
  (...insert components here!)
</DatabaseContextProvider>

...then invoke inside a component and just use it:

import { useContext } from 'react';
import { DatabaseContext } from '.../databaseContext';
...
const { data, functions, andMore } = useContext(DatabaseContext);

Barrels...

You may have already noticed that there are actually many [ index.js ] files peppered throughout the app. These are known as "barrel" exports, and have a few advantages when dealing with a complex file-directory. The index file in the [ components ] folder has a short explanation, but I'll also put it here:

/*
|------------------------------------------------------
| BARREL EXPORT FILE
|------------------------------------------------------
| How-To barrel-export components:
| export { default as Comp1 } from './comp1/comp1.js' (omit .js)
|
| Why? Readability and (to an extent) testing:
| import { Comp1, Comp2, Comp3, Comp4 } from './components'
| import { Route1, Route2, Route3, Route4 } from './routes'
*/
export { default as LoginForm } from './loginForm/loginForm'
export { default as Header } from './header/header'
etc...

You can see this in action in [ app.js ]:

import {
  HomeRoute,
  DashboardRoute,
  LoginRoute,
  RegisterRoute,
  PrivateRoute,
  PublicRoute,
} from 'src/routes';

Note that the import doesn't point to the index file. Node perceives [ index.js ] files as points of entry and the default file to grab exports from, essentially making it an implicit file in import statements


app:

Nothing much to say. This is a basic point-of-entry using React-Router. The switch at the top level acts as a router for pointing those logged in/out to the right destination.


routes:

These essentially just import and render components, acting as entry points to component trees. However, I'll briefly cover...

utils:

Private/Public-Routes: This serves as a UX enhancement, both preventing users not logged in from accessing the app, and already logged in users from accessing the Login page.


components:

I won't cover every component individually, but take a more broad-stroke approach, mentioning any note-worthy features when necessary

mainContaner:

This acts like a new "root" component, much like the App component. There's some basic state handling at the top level, and another switch that takes care of the app proper, with the various extra context providers taking care of dynamic database operations.

a note on forms:

This file - src/helpers/formFields.js - is the main "constructor" for rendering forms throughout the app. Each export contains some schema data and a single method that uses the schema data and any necessary state/handlers passed in to return an array of labels and inputs. Mainly, this keeps the component files much, much leaner and easier to read!


Contact Derek:

Github - musicMan1337

LinkedIn - Derek-8Bit-Nellis

Facebook - Derek Nellis

Instagram - @derek.8bit.nellis

Contact Mark:

Github - Mark-The-Dev

LinkedIn - Mark Marcello

Contact Russell:

Github - Russjames92

<<<<<<< HEAD

Github -

LinkedIn -

=======

LinkedIn - Russell Champlain

a1e4c43fd25ec404b1e62a7569897a2b53e67f66