Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expense app Jahil Khalfe #31

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"env": {
"browser": true,
"es2021": true,
"jest": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["react", "react-hooks", "@typescript-eslint", "prettier"],
"rules": {
"prettier/prettier": "error",
"react/react-in-jsx-scope": "off",
"camelcase": "error",
"spaced-comment": "error",
"quotes": ["error", "single"],
"no-duplicate-imports": "error"
},
"settings": {
"react": {
"version": "detect"
},
"import/resolver": {
"typescript": {}
}
}
}
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
.idea
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"semi": false,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all",
"jsxSingleQuote": true,
"bracketSpacing": true
}
130 changes: 95 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,119 @@
The task is to create an income/expense web app. The app should have two screens. The app should be written using the technologies mentioned in the Technologies section.
<div id="top"></div>

[![LinkedIn][linkedin-shield]][linkedin-url]

## Data layer
## About the project

There are two entities in the app: Category and Transaction
This project forms part of the take home task assigned for a frontend engineering role at [Datasapiens](https://www.datasapiens.co.uk/).
Note there is a link to the app in the repo about section on the top right corner.

### Category
The core focus of the solution:
* List Categories.
* List Transactions.
* Add a Category.
* Remove a Category.
* Add a transaction.
* Include a home route and a graphs route.
* Filter transactions depending on the existence of category.

Represents one category of transaction. As examples of categories: Salary, Gifts, Food, Going out, Traveling. There must be pre-defined categories in the app from the beginning (3-5 is enough).
<p align="right">(<a href="#top">back to top</a>)</p>

Should have following fields

- id
- label

### Transaction
### Technologies and Libraries used

Should have following fields
The core libraries are listed here:

- id
- label
- date
- amount (negative value means expense, positive value means income)
- category (reference by category id)
* [ReactJS](https://reactjs.org/)
* [MaterialUI](https://mui.com/)
* [Typescript](https://www.typescriptlang.org/)
* [CreatReactApp](https://create-react-app.dev/)
* [Formik](https://formik.org/)
* [Yup](https://github.com/jquense/yup)
* [ESLint](https://eslint.org/)
* [Prettier](https://prettier.io/)

## Screens
ESLint and prettier are set up as combined config. Formatting will run as part of linting rules.

### Home
<p align="right">(<a href="#top">back to top</a>)</p>

This is the default screen and app entry point. This screen should have a table of transactions and a form for adding a new transaction. Users should not be able to remove transactions. Also, on this screen, there should be a list of categories with the ability to add/remove categories. It's up to you to decide what happens to transactions in category when the category gets deleted.
## Getting Started

### Graph(s)
### Prerequisites

This screen should have a graph or multiple graphs to represent the data. It's up to you to decide how exactly to visualize the data. To give you an example: a graph representing total spends per category.
### Installation

## Technologies
1. ```shell
yarn
```
2. You should have no errors after installation and that is pretty much it for installation.

- Typescript
- SCSS Modules
- React version 16.8 and up, please make sure to use Hooks
- Redux version compatible with React version of choice
- Use `localStorage` as a DB for the app
<p align="right">(<a href="#top">back to top</a>)</p>

Usage of any additional libraries, such as react-router is allowed.

## How to participate
<div id="usage"></div>
## Usage

There are 3 simple steps
Here will follow steps to run the project.
* To start the application in watch mode
```shell
yarn start
```
* To lint and format the code
```shell
yarn lint
```
* To fix linting and formatting
```shell
yarn lint:fix
```

Alternatively there is the docker route `docker-compose up -d`
After the project is running dev you can open it on http://localhost:3000/.

1. Fork this repository
2. Complete the task in your repository
3. Create a PR to this repository
<p align="right">(<a href="#top">back to top</a>)</p>

Afterwards we will contact you, please make sure you have contact details in your GitHub profile.
## Roadmap

Tip: you can [deploy your application](https://www.freecodecamp.org/news/deploy-a-react-app-to-github-pages/) for demo on github pages for free
- [x] List Categories
- [x] List Transactions
- [x] Add a Category
- [x] Remove a Category
- [X] Add a transaction
- [X] Include a home route and a graphs route
- [X] Filter transactions depending on the existence of category
- [X] Render Graphs that will dynamically update after date has been added or removed

## Follow up
### Implementation

_Library Selection_
* ReactJS - The required tool for the job.
* Material UI - Quick multi select.
* Typescript - For some added Type safety to tighten up the data contract across various segments of the app. Also aids in catching
bugs that you might have missed.
* Prettier - Formats the code.
* ESLint - Enforce som standards and rules. Basic configuration.
* Formik - Quick and easy forms.
* Yup - Form validation.

_Start Command_ `yarn start` (<a href="#usage">Refer to the usage section</a>)

### General
Given more time I would Implement the following.
* In the ideal scenario the api would be paginated on the server side.
* Add unit test and push repo coverage to an acceptable level.
* Do some proper UI/UX with a better more fluent design.
* Setup async handling for data calls like redux-thunk or redux-saga.
* Preload with lots of data.
* When we absolutely have to render long lists of data we can virtualize the lists for performance. React 18 might cover this.
* Config setup for test, staging and prod.
* Implement path aliases for module imports.
* Error handling and tracking.

<p align="right">(<a href="#top">back to top</a>)</p>


[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
[linkedin-url]: https://www.linkedin.com/in/jahil-khalfe/

Happy coding 🚀
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: '3.5'

services:
expense-app:
image: node:lts
volumes:
- .:/app
ports:
- 3000:3000
working_dir: /app
command: bash -c "yarn && yarn start"
4 changes: 4 additions & 0 deletions global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module '*.module.scss' {
const classes: { [key: string]: string }
export default classes
}
71 changes: 71 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"name": "expense-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.9.3",
"@emotion/styled": "^11.9.3",
"@mui/icons-material": "^5.8.4",
"@mui/material": "^5.8.4",
"@reduxjs/toolkit": "^1.8.1",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.1",
"@testing-library/user-event": "^14.1.1",
"@types/jest": "^27.4.1",
"@types/node": "^17.0.25",
"@types/react": "^18.0.6",
"@types/react-dom": "^18.0.2",
"@types/recharts": "^1.8.23",
"formik": "^2.2.9",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-google-charts": "^4.0.0",
"react-redux": "^8.0.1",
"react-router-dom": "6",
"react-scripts": "5.0.1",
"recharts": "^2.1.10",
"typescript": "^4.6.0",
"web-vitals": "^2.1.0",
"yup": "^0.32.11"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint --ext .tsx,.ts,.tsx src/",
"lint:fix": "yarn lint --fix"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.28.0",
"@typescript-eslint/parser": "^5.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^2.7.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.5.0",
"prettier": "^2.6.2",
"sass": "^1.52.3",
"typed-scss-modules": "^6.5.0",
"typescript-plugin-css-modules": "^3.4.0"
}
}
Binary file added public/favicon.ico
Binary file not shown.
43 changes: 43 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React Redux App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Binary file added public/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/logo512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
3 changes: 3 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
Loading