Skip to content

Commit

Permalink
Merge pull request #2 from ClaytonSiby/develop
Browse files Browse the repository at this point in the history
Implement React-Typescript App for Bookstore
  • Loading branch information
ClaytonSiby authored Oct 24, 2023
2 parents a7278fd + 338e9fc commit 6ca03dc
Show file tree
Hide file tree
Showing 35 changed files with 6,668 additions and 264 deletions.
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = {
'react/prop-types': 'off',
'react/jsx-uses-react': 'off',
'react/react-in-jsx-scope': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
},
}
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
name: helm_ci

on:
push:
branches:
- main
- develop

jobs:
build-and-test:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build
node_modules
.vscode
13 changes: 13 additions & 0 deletions .hintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": [
"development"
],
"hints": {
"axe/forms": [
"default",
{
"select-name": "off"
}
]
}
}
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
# helm_bookstore_app
Add books to a shelf, read later, edit the book information, and categorize your books.
<h4>
This is an MVP version of a bookstore where you can keep all your favorite books together in one easy to manage place. You can Add more books, View a book's details, Update a book's information, and Delete it from your collection. This version allows your to do all these functionalities with ease.
</h4>

<ins>**Application Functionality**</ins>

![App Functionality](/src/assets/images/helm_bookstore.gif)

<ins>**Application Setup Instructions**</ins>

<h6>Make sure you have the latest version of [Node](https://nodejs.org/en/) and follow this instructions to setup and run the application on you local environment:</h6>

- `git clone https://github.com/ClaytonSiby/helm_bookstore_app.git` <br />
- `cd helm_bookstore_app` <br />
- `yarn install` <br />
- `yarn start` <br />

<ins>**Cool dev tool**</ins>

<h6>
This repository is setup to run a consistent default code format with Prettier and linting with Eslint. Before commit, lint-staged and Husky is ured run enforce these rules so that every commit adheres to the standards set for everyone contributing to the repository.
</h6>

<ins>**Husky and Lint-Stage Sample**</ins>

![husky-lint](/src/assets/images/husky-lintstaged.png)
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
}
34 changes: 32 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,53 @@
"description": "bookstore app pulling data from the helm_bookstore_api",
"main": "index.js",
"scripts": {
"test": "test",
"test": "jest",
"start": "webpack serve --config webpack/webpack.config.js --env env=dev",
"build": "webpack --config webpack/webpack.config.js --env env=prod",
"lint": "eslint --fix \"./src/**/*.{js,jsx,ts,tsx,json}\"",
"format": "prettier --write \"./src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\""
},
"author": "ClaytonSiby",
"license": "ISC",
"engines": {
"node": "18.18.0",
"npm": "9.8.1"
},
"dependencies": {
"@testing-library/jest-dom": "^6.1.3",
"add": "^2.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-router-dom": "^6.16.0",
"react-scripts": "^5.0.1",
"react-spinners": "^0.13.8",
"yarn": "^1.22.19"
},
"devDependencies": {
"@babel/core": "^7.23.0",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/plugin-syntax-flow": "^7.22.5",
"@babel/plugin-transform-private-property-in-object": "^7.22.11",
"@babel/plugin-transform-react-jsx": "^7.22.15",
"@babel/preset-env": "^7.22.20",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.23.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
"@popperjs/core": "^2.11.8",
"@reduxjs/toolkit": "^1.9.7",
"@testing-library/react": "^14.0.0",
"@types/jest": "^29.5.5",
"@types/mocha": "^10.0.2",
"@types/react": "^18.2.25",
"@types/react-dom": "^18.2.11",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"autoprefixer": "^10.4.16",
"axios": "^1.5.1",
"axios-mock-adapter": "^1.22.0",
"babel-jest": "^29.7.0",
"babel-loader": "^9.1.3",
"bootstrap": "^5.3.2",
"css-loader": "^6.8.1",
"eslint": "^8.51.0",
"eslint-config-prettier": "^9.0.0",
Expand All @@ -41,10 +62,19 @@
"eslint-plugin-react-hooks": "^4.6.0",
"html-webpack-plugin": "^5.5.3",
"husky": "4",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"lint-staged": "^14.0.1",
"postcss": "^8.4.31",
"postcss-loader": "^7.3.3",
"prettier": "^3.0.3",
"react-redux": "^8.1.3",
"react-refresh": "^0.14.0",
"react-test-renderer": "^18.2.0",
"sass": "^1.69.1",
"sass-loader": "^13.3.2",
"style-loader": "^3.3.3",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
Expand Down
Binary file added src/.DS_Store
Binary file not shown.
24 changes: 21 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
import './styles.css'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import BookList from './components/BookList'
import UpdateBook from './components/UpdateBook'
import Navbar from './components/Navbar'
import Footer from './components/Footer'
import './assets/styles/main.scss'

const App = () => {
return <h1>Helm BookStore</h1>
const App: React.FC = () => {
return (
<>
<Navbar />
<div className="container main-content">
<Router>
<Routes>
<Route path="/" element={<BookList />} />
<Route path="/:bookId" element={<UpdateBook />} />
</Routes>
</Router>
</div>
<Footer />
</>
)
}

export default App
25 changes: 25 additions & 0 deletions src/__tests__/BookList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { render, waitFor } from '@testing-library/react'
import { Provider } from 'react-redux'
import { store } from '../app/store'
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'
import BookList from '../components/BookList'

const mock = new MockAdapter(axios)

it('should make a GET request when rendering BookList component', async () => {
const mockResponse = { books: [{ title: 'Book 1' }, { title: 'Book 2' }] }
mock.onGet('/api/books').reply(200, mockResponse)

// Render the BookList component
render(
<Provider store={store}>
<BookList />
</Provider>
)

// Wait for the GET request to complete
await waitFor(() => {
expect(mock.history.get.length).toBe(2)
})
})
5 changes: 5 additions & 0 deletions src/app/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from '../app/store'

export const useAppDispatch = () => useDispatch<AppDispatch>()
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
14 changes: 14 additions & 0 deletions src/app/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { configureStore } from '@reduxjs/toolkit'
import { reducer as bookReducer } from '../features/book/bookSlice'
import { reducer as categoryReducer } from '../features/category/categorySlice'

export const store = configureStore({
reducer: {
books: bookReducer,
categories: categoryReducer,
},
})

export type RootState = ReturnType<typeof store.getState>

export type AppDispatch = typeof store.dispatch
Binary file added src/assets/.DS_Store
Binary file not shown.
Binary file added src/assets/images/helm_bookstore.gif
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 src/assets/images/husky-lintstaged.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions src/assets/styles/main.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
body {
box-sizing: border-box;
margin: 0;
padding: 0;
font-size: 15px;
font-family: Arial, Helvetica, sans-serif;
background: rgb(221, 218, 218) !important;
margin: 0;
padding: 0;
height: 100vh;

.main-content {
margin-top: 3.5rem;
height: calc(100vh - 3.5rem);

.loadingSpinner {
display: flex;
justify-content: center;
align-items: center;
height: calc(85vh - 2.5rem);
}

#floatingTextarea,
#inlineFormSelectPref {
min-height: 10rem;
}
}

.bookDetailsPage {
height: calc(100vh - 7rem);
max-width: 500px;
margin: 0 auto;
}
}
51 changes: 51 additions & 0 deletions src/components/AddBookModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react'
import CreateBook from '../BookForm'

const AddBookModal = () => {
return (
<div>
<button
type="button"
className="btn bg-info-subtle"
data-bs-toggle="modal"
data-bs-target="#staticBackdrop"
>
Add New book
</button>

<div
className="modal fade"
id="staticBackdrop"
data-bs-backdrop="static"
data-bs-keyboard="false"
tabIndex={-1}
aria-labelledby="staticBackdropLabel"
aria-hidden="true"
>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content bg-info-subtle">
<div className="modal-header border-bottom border-info">
<h1
className="modal-title fs-5 text-body-tertiary"
id="staticBackdropLabel"
>
Book Information
</h1>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">
<CreateBook />
</div>
</div>
</div>
</div>
</div>
)
}

export default AddBookModal
Loading

0 comments on commit 6ca03dc

Please sign in to comment.