Commit 28f95b55 authored by Philippe Fonzin's avatar Philippe Fonzin

Merge branch 'feat/react' into 'master'

Add React/Redux base to warehouse

See merge request !1
parents a3ee1ade 0db8e61f
......@@ -2275,6 +2275,15 @@
"@types/node": "*"
}
},
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/html-minifier-terser": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz",
......@@ -2345,11 +2354,37 @@
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz",
"integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA=="
},
"@types/prop-types": {
"version": "15.7.3",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
},
"@types/q": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
},
"@types/react": {
"version": "17.0.4",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.4.tgz",
"integrity": "sha512-onz2BqScSFMoTRdJUZUDD/7xrusM8hBA2Fktk2qgaTYPCgPvWnDEgkrOs8hhPUf2jfcIXkJ5yK6VfYormJS3Jw==",
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"@types/react-redux": {
"version": "7.1.16",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz",
"integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==",
"requires": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
......@@ -2358,6 +2393,11 @@
"@types/node": "*"
}
},
"@types/scheduler": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
"integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA=="
},
"@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
......@@ -3060,6 +3100,14 @@
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.0.tgz",
"integrity": "sha512-1uIESzroqpaTzt9uX48HO+6gfnKu3RwvWdCcWSrX4csMInJfCo1yvKPNXCwXFRpJqRW25tiASb6No0YH57PXqg=="
},
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"axobject-query": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
......@@ -4800,6 +4848,11 @@
}
}
},
"csstype": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz",
"integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw=="
},
"cyclist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
......@@ -4865,6 +4918,11 @@
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
"integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw="
},
"deep-diff": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz",
"integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ="
},
"deep-equal": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
......@@ -7156,6 +7214,14 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
}
},
"hoopy": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
......@@ -12460,11 +12526,29 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
},
"react-icons": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.2.0.tgz",
"integrity": "sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ=="
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-redux": {
"version": "7.2.4",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz",
"integrity": "sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA==",
"requires": {
"@babel/runtime": "^7.12.1",
"@types/react-redux": "^7.1.16",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^16.13.1"
}
},
"react-refresh": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
......@@ -12651,6 +12735,27 @@
"strip-indent": "^3.0.0"
}
},
"redux": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz",
"integrity": "sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"redux-logger": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz",
"integrity": "sha1-91VZZvMJjzyIYExEnPC69XeCdL8=",
"requires": {
"deep-diff": "^0.3.5"
}
},
"redux-thunk": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
"integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
},
"regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
......
......@@ -6,9 +6,15 @@
"@testing-library/jest-dom": "^5.12.0",
"@testing-library/react": "^11.2.6",
"@testing-library/user-event": "^12.8.3",
"axios": "^0.21.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.2.0",
"react-redux": "^7.2.4",
"react-scripts": "4.0.3",
"redux": "^4.1.0",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"web-vitals": "^1.1.1"
},
"scripts": {
......
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
import Header from "./components/header/Header";
import Footer from "./components/footer/Footer";
import OrderIndex from "./components/order/OrderIndex"
const App = () => {
return (
<div className="app">
<Header />
<OrderIndex />
<Footer />
</div>
);
}
export default App;
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
import * as OrderAPIUtil from '../util/orders_api_util';
export const RECEIVE_ORDERS = 'RECEIVE_ORDERS';
export const RECEIVE_ORDER = 'RECEIVE_ORDER';
export const UPDATE_ORDER = 'UPDATE_ORDER';
const receiveOrders = (payload) => ({
type: RECEIVE_ORDERS,
payload,
})
const receiveOrder = (order) => ({
type: RECEIVE_ORDER,
order,
})
const updateOrder = (order) => ({
type: UPDATE_ORDER,
order,
})
export const fetchOrders = () => (dispatch) => {
OrderAPIUtil.getOrders()
.then(res => {
dispatch(receiveOrders(res))
});
}
export const createOrder = (order) => (dispatch) =>
OrderAPIUtil.createOrder(order)
.then(res => {
dispatch(receiveOrder(res))
});
export const editOrder = (order) => (dispatch) =>
OrderAPIUtil.editOrder(order)
.then(res => {
dispatch(updateOrder(res))
});
\ No newline at end of file
import React from "react";
const Footer = () => {
return <div>Footer</div>;
};
export default Footer;
import React from 'react';
const Header = () => {
return (
<div>
Header
</div>
)
}
export default Header;
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import OrderIndexItem from './OrderIndexItem';
import { connect } from "react-redux";
import { createOrder, fetchOrders, editOrder } from '../../actions/order_actions';
const OrderIndex = ({
orders,
fetchOrders,
createOrder,
editOrder,
}) => {
const [fetchAttempted, setFetchAttempted] = useState(false);
useEffect(() => {
if (!fetchAttempted) {
setFetchAttempted(true);
fetchOrders();
}
}, [fetchOrders, fetchAttempted])
return (
<div>
<h1>Order Index</h1>
<button onClick={createOrder}>Create New Order</button>
<button onClick={editOrder}>Update Order</button>
{orders.allIds.map(orderId => {
const order = orders.byId[orderId];
return (
<OrderIndexItem
key={order.id}
order={order}
/>
)
})}
</div>
)
}
const mapStateToProps = (state) => ({
orders: state.entities.orders,
})
const mapDispatchToProps = dispatch => ({
fetchOrders: () => dispatch(fetchOrders()),
createOrder: order => dispatch(createOrder(order)),
editOrder: order => dispatch(editOrder(order)),
})
export default connect(mapStateToProps, mapDispatchToProps)(OrderIndex)
import React from 'react';
const OrderIndexItem = ({ order }) => {
return (
<div>
{order.orderId} {order.status}
</div>
)
};
export default OrderIndexItem;
......@@ -3,13 +3,23 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import configureStore from './store/store';
import { Provider } from 'react-redux';
document.addEventListener('DOMContentLoaded', () => {
const store = configureStore();
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
});
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
......
import { combineReducers } from "redux";
import orders from "./orders_reducer";
const EntitiesReducer = combineReducers({
orders,
});
export default EntitiesReducer;
import {
RECEIVE_ORDER,
RECEIVE_ORDERS,
UPDATE_ORDER,
} from "../../actions/order_actions";
const initialState = {
byId: {},
allIds: [],
};
const OrdersReducer = (oldState = initialState, action) => {
Object.freeze(oldState);
const newState = { ...oldState };
const order = action.order || null;
switch (action.type) {
case RECEIVE_ORDERS:
return action.payload;
case RECEIVE_ORDER:
newState.byId[order.id] = order;
newState.allIds.unshift(order.id);
return newState;
case UPDATE_ORDER:
newState.byId[order.id] = order;
return newState;
default:
return oldState;
}
};
export default OrdersReducer;
import { combineReducers } from "redux";
import entities from "./entities/entities_reducer";
const RootReducer = combineReducers({
entities,
});
export default RootReducer;
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
import { createStore, applyMiddleware } from 'redux';
import { createLogger } from 'redux-logger';
import thunk from 'redux-thunk';
import rootReducer from '../reducers/root_reducer';
const logger = createLogger();
const configureStore = (preloadedState = {}) => (
createStore(
rootReducer,
preloadedState,
applyMiddleware(thunk, logger),
)
)
export default configureStore;
\ No newline at end of file
// import axios from 'axios';
const sampleGetAll = {
allIds: ["1", "2", "3"],
byId: {
"1": {
id: "1",
orderId: "o1",
status: "unfulfilled",
},
"2": {
id: "2",
orderId: "o2",
status: "unfulfilled",
},
"3": {
id: "3",
orderId: "o3",
status: "unfulfilled",
},
},
};
const sampleNew = {
id: "4",
orderId: "o4",
status: "unfulfilled",
};
const sampleUpdateFul = {
id: "3",
orderId: "o3",
status: "fulfilled",
};
const sampleUpdateCan = {
id: "2",
orderId: "o2",
status: "cancelled",
};
const getAllPromise = new Promise( (resolve, reject) => {
resolve(sampleGetAll)
})
const createNewPromise = new Promise( (resolve, reject) => {
resolve(sampleNew)
})
const updateFulfillPromise = new Promise( (resolve, reject) => {
resolve(sampleUpdateFul)
})
const updateCancelPromise = new Promise( (resolve, reject) => {
resolve(sampleUpdateCan)
})
export const getOrders = () => {
return getAllPromise;
};
export const createOrder = (order) => {
return createNewPromise;
}
export const editOrder = (order) => {
return updateFulfillPromise;
}
// export const getOrders =() => {
// return axios.get("http://localhost:8080/api/orders");
// }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment