Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
44bf4ef
feat(entire-project)-initialBaseProject
yengobilly4063 Jan 15, 2022
6239749
feat(entire-project)-addedComponentsAndCss
yengobilly4063 Jan 16, 2022
1feb49b
Merge pull request #1 from yengobilly4063/development
yengobilly4063 Jan 16, 2022
d511c2f
feat(reducers)-addReducersForStateManagement
yengobilly4063 Jan 16, 2022
7a893e0
feat(transcation-reducers)-addedReducersForTransactionEntity
yengobilly4063 Jan 16, 2022
95c9109
Merge pull request #2 from yengobilly4063/development
yengobilly4063 Jan 17, 2022
af1cb8a
feat(graphs)-addedPieGraphs
yengobilly4063 Jan 18, 2022
dc78785
added update transaction on category delete, code cleanup
yengobilly4063 Jan 18, 2022
735982d
prepering for deploy on gh-pages
yengobilly4063 Jan 18, 2022
c3a1338
...
yengobilly4063 Jan 18, 2022
92542d6
Merge branch 'main' of github.com:yengobilly4063/expense-app
yengobilly4063 Jan 18, 2022
147d118
fixed npm package issues
yengobilly4063 Jan 18, 2022
f73f670
Merge pull request #3 from yengobilly4063/development
yengobilly4063 Jan 18, 2022
f66f40f
..
yengobilly4063 Jan 18, 2022
4254eaf
Merge pull request #4 from yengobilly4063/development
yengobilly4063 Jan 18, 2022
9e10d44
fix package.json scripts
yengobilly4063 Jan 18, 2022
d6ed77b
Merge pull request #5 from yengobilly4063/development
yengobilly4063 Jan 18, 2022
6721c3b
fix for netlify build error
yengobilly4063 Jan 18, 2022
136e0d9
Merge pull request #6 from yengobilly4063/development
yengobilly4063 Jan 18, 2022
4b5b6d3
refactore and localstorage fix for categories
yengobilly4063 Jan 18, 2022
7c41d4e
Merge pull request #7 from yengobilly4063/development
yengobilly4063 Jan 18, 2022
5b8906b
fixed uuid auto generate id producing new ids on page refresh
yengobilly4063 Jan 18, 2022
782a717
Merge pull request #8 from yengobilly4063/development
yengobilly4063 Jan 18, 2022
4d63046
...
yengobilly4063 Jan 18, 2022
13973c1
Merge pull request #9 from yengobilly4063/development
yengobilly4063 Jan 18, 2022
86e7882
bug fix on 0 transaction value, graphs display fix
yengobilly4063 Jan 19, 2022
429a559
Merge pull request #10 from yengobilly4063/development
yengobilly4063 Jan 19, 2022
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
23 changes: 23 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/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*
11,798 changes: 11,798 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "expense-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.4.0",
"@types/node": "^16.11.19",
"@types/node-sass": "^4.11.2",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/react-redux": "^7.1.22",
"@types/react-router-dom": "^5.3.2",
"@types/uuid": "^8.3.4",
"chart.js": "^3.7.0",
"node-sass": "^7.0.1",
"react": "^17.0.2",
"react-chartjs-2": "^4.0.0",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^5.3.0",
"react-scripts": "5.0.0",
"redux": "^4.1.2",
"redux-thunk": "^2.4.1",
"typescript": "^4.5.4",
"uuid": "^8.3.2",
"web-vitals": "^2.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"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"
]
}
}
Binary file added public/datasapiens.ico
Binary file not shown.
17 changes: 17 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/datasapiens.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" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Expense App - DataSapiens</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</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:
23 changes: 23 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import MainLayout from "./components/layout/MainLayout";
import { Switch, Route, Redirect } from "react-router-dom";
import Home from "./pages/home/Home";
import Graph from "./pages/graph/Graph";
import NotFound from "./pages/not-found/NotFound";

function App() {
return (
<React.Fragment>
<MainLayout>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/graphs" exact component={Graph} />
<Route path="/not-found" exact component={NotFound} />
<Redirect to="/not-found" from="*" />
</Switch>
</MainLayout>
</React.Fragment>
);
}

export default App;
7 changes: 7 additions & 0 deletions src/components/card/Card.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.card {
background-color: white;
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.5);
padding: 0.5rem;
border-radius: 5px;
margin-bottom: 1rem;
}
11 changes: 11 additions & 0 deletions src/components/card/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";
import styles from "./Card.module.scss";
interface IProps {
children?: JSX.Element | Array<JSX.Element>;
}

const Card: React.FC<IProps> = ({ children }) => {
return <div className={styles.card}>{children}</div>;
};

export default Card;
71 changes: 71 additions & 0 deletions src/components/categories/category-form/CategoryForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { FormEvent, useState, useRef } from "react";
import { ICategory } from "../../../interfaces";
import { addCategory } from "../../../store/reducers/categories/category.action-creators";
import formStyles from "../../styles/Form.module.scss";
import { useDispatch } from "react-redux";
import { v4 as uuidv4 } from "uuid";

const initialInputState: ICategory = { label: "" };

const CategoryForm: React.FC = () => {
const dispatch = useDispatch();
const formRef = useRef<HTMLFormElement>(null);

const [input, setInput] = useState<ICategory>(initialInputState);

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = event.currentTarget;
setInput((prevInput) => {
return {
...prevInput,
[name]: value,
};
});
};

const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (!input.label || input.label.length < 4) {
alert("Category name is required and 4 characters long");
return;
}
const newCategory: ICategory = {
id: uuidv4(),
label: input.label,
};
// setInput(initialInputState);
dispatch(addCategory(newCategory));
event.currentTarget.reset();
clearForm();
};

const clearForm = () => {
if (null !== formRef.current) {
formRef.current?.reset();
}
};

return (
<form className={formStyles.form} onSubmit={handleSubmit} ref={formRef} id="form">
<h1 className={formStyles.title}>Add Category</h1>
<div className={formStyles.control}>
<label htmlFor="label">
Category Name<span className="asterisk">*</span>
</label>
<input
type="text"
placeholder="Category name"
value={input.label}
name="label"
id="label"
onChange={handleInputChange}
/>
</div>
<div className={formStyles.actions}>
<button>Add Category</button>
</div>
</form>
);
};

export default CategoryForm;
25 changes: 25 additions & 0 deletions src/components/categories/category-item/CategoryItem.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.item {
padding: 0.5rem;
display: flex;
justify-content: space-between;
align-items: center;

border-bottom: 1px solid steelblue;
border-top: 1px solid steelblue;

button {
padding: 0.25rem;
font: inherit;
cursor: pointer;
color: slategrey;
border: 1px solid crimson;
border-radius: 4px;
font-weight: bold;

&:hover,
&:active {
color: white;
background-color: crimson;
}
}
}
28 changes: 28 additions & 0 deletions src/components/categories/category-item/CategoryItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import { ICategory } from "../../../interfaces";
import { deleteCategory } from "../../../store/reducers/categories/category.action-creators";
import styles from "./CategoryItem.module.scss";
import { useDispatch } from "react-redux";
import { updateTransaction } from "../../../store/reducers/transactions/transaction.action-creators";

interface IProps {
category: ICategory;
}

const CategoryItem: React.FC<IProps> = ({ category }) => {
const dispatch = useDispatch();

const handleCategoryDelete = () => {
dispatch(deleteCategory(category));
dispatch(updateTransaction(category.id!));
};

return (
<div className={styles.item}>
<span>{category.label}</span>
<button onClick={handleCategoryDelete}>Delete</button>
</div>
);
};

export default CategoryItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.categoryListHeader {
margin-top: 1rem;
padding: 0.5rem;
display: flex;
justify-content: space-between;
color: #3d50a7;
font-family: "Ubuntu";
font-weight: 500;
span {
&:last-of-type {
padding-right: 0.5rem;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from "react";
import styles from "./CategoryListHeader.module.scss";
const CategoryHeaderList: Array<string> = ["Category Name", "Actions"];

const CategoryListHeader: React.FC = () => {
return (
<div className={styles.categoryListHeader}>
{CategoryHeaderList.map((header: string, index: number) => (
<span key={index}>{header}</span>
))}
</div>
);
};

export default CategoryListHeader;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.list {
display: flex;
flex-direction: column;
}
35 changes: 35 additions & 0 deletions src/components/categories/category-list/CategoryList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react";
import { ICategory } from "../../../interfaces";
import NoContent from "../../no-content/NoContent";
import CategoryItem from "../category-item/CategoryItem";
import CategoryListHeader from "../category-list-header/CategoryListHeader";
import styles from "./CategoryList.module.scss";
import { useSelector } from "react-redux";
import { getCategories } from "../../../store/reducers/categories/category.reducer";

const displayContent = (categories: Array<ICategory>) => {
let content;
if (categories.length === 0) {
content = <NoContent title="categories" />;
} else {
content = (
<React.Fragment>
<h1>Categories</h1>
<CategoryListHeader />
<div className={styles.list}>
{categories.map((category: ICategory) => (
<CategoryItem category={category} key={category.id} />
))}
</div>
</React.Fragment>
);
}
return content;
};

const CategoryList: React.FC = () => {
const categories = useSelector(getCategories);
return <div>{displayContent(categories)}</div>;
};

export default CategoryList;
5 changes: 5 additions & 0 deletions src/components/chart/PieChart.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.chartHeader {
text-align: center;
font-size: 2rem;
padding: 1rem;
}
Loading