diff --git a/00 Base/config/webpack/base.js b/00 Base/config/webpack/base.js
index dff4c7b..d89604e 100644
--- a/00 Base/config/webpack/base.js
+++ b/00 Base/config/webpack/base.js
@@ -8,10 +8,7 @@ module.exports = merge(
{
context: helpers.resolveFromRootPath('src'),
resolve: {
- extensions: ['.js', '.ts', '.tsx'],
- modules: [
- 'node_modules'
- ]
+ extensions: ['.js', '.ts', '.tsx', '.css', '.scss', '.less'],
},
entry: {
app: ['./index.tsx'],
@@ -28,14 +25,18 @@ module.exports = merge(
babelCore: '@babel/core',
}
},
+ {
+ test: /\.css$/,
+ loaders: ['style-loader', 'css-loader'],
+ },
+ {
+ test: /\.s[ac]ss$/i,
+ loaders: ['style-loader', 'css-loader', 'sass-loader'],
+ },
{
test: /\.less$/,
- use: [
- { loader: 'style-loader' },
- { loader: 'css-loader' },
- { loader: 'less-loader' }
- ]
- }
+ use: ['style-loader', 'css-loader', 'less-loader'],
+ },
],
},
optimization: {
diff --git a/00 Base/package.json b/00 Base/package.json
index 2e1ce01..acf78fd 100644
--- a/00 Base/package.json
+++ b/00 Base/package.json
@@ -13,10 +13,12 @@
"author": "arp82",
"license": "MIT",
"dependencies": {
+ "@material-ui/core": "^4.9.9",
+ "@material-ui/icons": "^4.9.1",
+ "axios": "^0.19.2",
+ "babel-polyfill": "^6.26.0",
"@babel/preset-react": "^7.9.4",
"@babel/preset-stage-0": "^7.8.3",
- "@material-ui/core": "^4.9.9",
- "axios": "^0.19.0",
"babel-core": "^7.0.0-bridge.0",
"identity-obj-proxy": "^3.0.0",
"jest-transform-css": "^2.0.0",
@@ -24,9 +26,10 @@
"react-dom": "^16.8.6",
"react-redux": "^7.2.0",
"react-router-dom": "^5.0.1",
- "react-test-renderer": "^16.13.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
+ "sass-loader": "^8.0.2",
+ "react-test-renderer": "^16.13.1",
"sinon": "^9.0.1",
"style-loader": "^1.1.3",
"ts-jest": "^25.3.1"
@@ -43,14 +46,20 @@
"@types/react-dom": "^16.8.4",
"@types/react-router-dom": "^4.3.4",
"awesome-typescript-loader": "^5.2.1",
+ "html-webpack-plugin": "^3.2.0",
+ "jest": "^24.8.0",
+ "less": "^3.11.1",
+ "less-loader": "^5.0.0",
+ "node-sass": "^4.13.1",
+ "redux-devtools-extension": "^2.13.8",
+ "rimraf": "^2.6.3",
+ "sass-loader": "^7.2.0",
+ "style-loader": "^1.1.3",
+ "ts-jest": "^24.0.2",
"babel-jest": "^25.2.6",
"css-loader": "^3.4.2",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
- "html-webpack-plugin": "^3.2.0",
- "jest": "^24.9.0",
- "less": "^3.11.1",
- "less-loader": "^5.0.0",
"react-addons-test-utils": "^15.6.2",
"redux-mock-store": "^1.5.4",
"typescript": "^3.5.2",
diff --git a/00 Base/src/app.tsx b/00 Base/src/app.tsx
index 93864a7..f234558 100644
--- a/00 Base/src/app.tsx
+++ b/00 Base/src/app.tsx
@@ -1,8 +1,9 @@
import * as React from 'react';
-import { MessagesSection } from './components';
+import { MyComponent } from './components/myComponent';
+import './styles.less';
-export const App: React.FunctionComponent = props => (
+export const App: React.FunctionComponent = (props) => (
-
+
);
diff --git a/00 Base/src/components/myComponent/index.ts b/00 Base/src/components/myComponent/index.ts
new file mode 100644
index 0000000..bcc7da0
--- /dev/null
+++ b/00 Base/src/components/myComponent/index.ts
@@ -0,0 +1 @@
+export { MyComponent } from './myComponent';
\ No newline at end of file
diff --git a/00 Base/src/components/myComponent/myComponent.tsx b/00 Base/src/components/myComponent/myComponent.tsx
new file mode 100644
index 0000000..529195e
--- /dev/null
+++ b/00 Base/src/components/myComponent/myComponent.tsx
@@ -0,0 +1,54 @@
+import * as React from 'react';
+
+import { useSelector, useDispatch } from 'react-redux';
+import {
+ /* fetchfruits,
+ deleteFruit,
+ addFruit, */
+ fetchPosts,
+ deletePost,
+ addPost,
+} from './../../redux/actions/index';
+import './styles.less';
+
+import Button from '@material-ui/core/Button';
+import Chip from '@material-ui/core/Chip';
+
+import { MyInputComponent } from '../myInputComponent/myInputComponent';
+export interface Props {
+ nameFromProps: string;
+}
+
+export const MyComponent: React.FunctionComponent = (props) => {
+ const { nameFromProps } = props;
+ const dispatch = useDispatch();
+ const posts = useSelector((state) => state.posts.posts);
+
+ return (
+ <>
+
+
Hello {nameFromProps}!
+
+
+ {!!posts
+ ? posts.map((el /* : Object */) => (
+ dispatch(deletePost(el.id))}
+ />
+ ))
+ : null}
+
+
dispatch(addPost(newPost))} />
+
+ >
+ );
+};
diff --git a/00 Base/src/components/myComponent/styles.less b/00 Base/src/components/myComponent/styles.less
new file mode 100644
index 0000000..3ec5f71
--- /dev/null
+++ b/00 Base/src/components/myComponent/styles.less
@@ -0,0 +1,12 @@
+.container {
+ text-align: center;
+ .chip-container {
+ display: block;
+ position: relative;
+ margin-top: 25px;
+ .MuiChip-root {
+ margin-left: 5px;
+ margin-top: 5px;
+ }
+ }
+}
diff --git a/00 Base/src/components/myInputComponent/index.ts b/00 Base/src/components/myInputComponent/index.ts
new file mode 100644
index 0000000..3b0b11d
--- /dev/null
+++ b/00 Base/src/components/myInputComponent/index.ts
@@ -0,0 +1 @@
+export { MyInputComponent } from './myInputComponent';
\ No newline at end of file
diff --git a/00 Base/src/components/myInputComponent/myInputComponent.tsx b/00 Base/src/components/myInputComponent/myInputComponent.tsx
new file mode 100644
index 0000000..bd63ca7
--- /dev/null
+++ b/00 Base/src/components/myInputComponent/myInputComponent.tsx
@@ -0,0 +1,31 @@
+import * as React from 'react';
+import TextField from '@material-ui/core/TextField';
+import { Add } from '@material-ui/icons';
+import './styles.less';
+
+export interface Props {
+ addPost: Function;
+}
+
+export const MyInputComponent: React.FunctionComponent = (props) => {
+ const { addPost } = props;
+ const [name, setName] = React.useState('');
+
+ return (
+
+
setName(e.target.value)}
+ />
+ {!!name ? (
+ {
+ addPost(name);
+ setName('');
+ }}
+ />
+ ) : null}
+
+ );
+};
diff --git a/00 Base/src/components/myInputComponent/styles.less b/00 Base/src/components/myInputComponent/styles.less
new file mode 100644
index 0000000..0af11b8
--- /dev/null
+++ b/00 Base/src/components/myInputComponent/styles.less
@@ -0,0 +1,9 @@
+.input-component {
+ .MuiFormControl-root {
+ margin-top: 10px;
+ }
+ .MuiSvgIcon-root {
+ margin-top: 35px;
+ color: #00ff00;
+ }
+}
diff --git a/00 Base/src/index.tsx b/00 Base/src/index.tsx
index 1725370..2c35ff9 100644
--- a/00 Base/src/index.tsx
+++ b/00 Base/src/index.tsx
@@ -1,16 +1,14 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
-import { App } from './app';
-import { Provider } from 'react-redux'
-import { createStore, compose, applyMiddleware } from 'redux'
-import {MessagesReducer} from './redux/reducers/MessagesReducer'
-import thunk from 'redux-thunk'
+import { Provider } from 'react-redux';
+import store from './redux/store';
-const MessagesStore = createStore(MessagesReducer,compose(applyMiddleware(thunk)));
+import { App } from './app';
+import 'babel-polyfill'
ReactDOM.render(
-
+
-,
-
- document.getElementById('root'));
+ ,
+ document.getElementById('root')
+);
diff --git a/00 Base/src/myApi/index.ts b/00 Base/src/myApi/index.ts
new file mode 100644
index 0000000..3cbca37
--- /dev/null
+++ b/00 Base/src/myApi/index.ts
@@ -0,0 +1 @@
+export { getListOfFruit, getPosts } from './myApi';
diff --git a/00 Base/src/myApi/myApi.ts b/00 Base/src/myApi/myApi.ts
new file mode 100644
index 0000000..8cd6d3d
--- /dev/null
+++ b/00 Base/src/myApi/myApi.ts
@@ -0,0 +1,24 @@
+import * as BEApi from './myBackEndApiEndpoint';
+import axios from 'axios';
+
+export const getListOfFruit = (): Promise => {
+ return BEApi.getFruits('http://fruityfruit.com')
+ .then(resolveFruits)
+ .catch(handleError);
+};
+
+const resolveFruits = (fruits: string[]) => {
+ return fruits;
+};
+
+const handleError = () => {
+ throw new Error('Where is my fruit???');
+};
+export const getPosts = (): any => {
+ return axios
+ .get('https://jsonplaceholder.typicode.com/posts')
+ .then(resolvePosts);
+};
+const resolvePosts = (posts: any) => {
+ return posts;
+};
diff --git a/00 Base/src/myApi/myBackEndApiEndpoint.ts b/00 Base/src/myApi/myBackEndApiEndpoint.ts
new file mode 100644
index 0000000..1457042
--- /dev/null
+++ b/00 Base/src/myApi/myBackEndApiEndpoint.ts
@@ -0,0 +1,12 @@
+export const getFruits = (_url: string) => {
+ return Promise.resolve([
+ 'grape',
+ 'pineapple',
+ 'watermelon',
+ 'orange',
+ 'lemon',
+ 'strawberry',
+ 'cherry',
+ 'peach',
+ ]);
+}
\ No newline at end of file
diff --git a/00 Base/src/redux/actions/fruitsActions.tsx b/00 Base/src/redux/actions/fruitsActions.tsx
new file mode 100644
index 0000000..81d68bf
--- /dev/null
+++ b/00 Base/src/redux/actions/fruitsActions.tsx
@@ -0,0 +1,28 @@
+import { GET_ALL_FRUITS, DELETE_FRUIT, ADD_FRUIT } from './../constants';
+import { getListOfFruit } from '../../myApi/index';
+
+export const getAllFruits = (fruits: String[]) => {
+ return {
+ type: GET_ALL_FRUITS,
+ payload: fruits,
+ };
+};
+export const fetchfruits = () => {
+ return (dispatch) => {
+ return getListOfFruit().then((res) => dispatch(getAllFruits(res)));
+ };
+};
+
+export const deleteFruit = (name: string) => {
+ return {
+ type: DELETE_FRUIT,
+ payload: name,
+ };
+};
+
+export const addFruit = (name: string) => {
+ return {
+ type: ADD_FRUIT,
+ payload: name,
+ };
+};
diff --git a/00 Base/src/redux/actions/index.ts b/00 Base/src/redux/actions/index.ts
new file mode 100644
index 0000000..af7b50e
--- /dev/null
+++ b/00 Base/src/redux/actions/index.ts
@@ -0,0 +1,7 @@
+export {
+ addFruit,
+ deleteFruit,
+ fetchfruits,
+ getAllFruits,
+} from './fruitsActions';
+export { fetchPosts, deletePost,addPost } from './postActions';
diff --git a/00 Base/src/redux/actions/postActions.tsx b/00 Base/src/redux/actions/postActions.tsx
new file mode 100644
index 0000000..0345d8e
--- /dev/null
+++ b/00 Base/src/redux/actions/postActions.tsx
@@ -0,0 +1,28 @@
+import { GET_POST_FROM_API,DELETE_POST,ADD_POST } from './../constants';
+import { getPosts } from '../../myApi/index';
+
+export const getPostFromApi = ( posts: Object[]) => {
+ return {
+ type: GET_POST_FROM_API,
+ payload: posts,
+ };
+};
+export const fetchPosts = () => {
+ return (dispatch) => {
+ return getPosts().then((res) => dispatch(getPostFromApi(res)));
+ };
+};
+
+ export const deletePost = (id: Number) => {
+ return {
+ type: DELETE_POST,
+ payload: id,
+ };
+};
+
+export const addPost = (name: string) => {
+ return {
+ type: ADD_POST,
+ payload: name,
+ };
+};
diff --git a/00 Base/src/redux/constants.ts b/00 Base/src/redux/constants.ts
new file mode 100644
index 0000000..1e7fd44
--- /dev/null
+++ b/00 Base/src/redux/constants.ts
@@ -0,0 +1,7 @@
+export const GET_ALL_FRUITS = 'GET_ALL_FRUITS';
+export const DELETE_FRUIT = 'DELETE_FRUIT';
+export const ADD_FRUIT = 'ADD_FRUIT';
+
+export const GET_POST_FROM_API = 'GET_POST_FROM_API';
+export const DELETE_POST = 'DELETE_POST';
+export const ADD_POST = 'ADD_POST';
diff --git a/00 Base/src/redux/reducers/fruitReducer.tsx b/00 Base/src/redux/reducers/fruitReducer.tsx
new file mode 100644
index 0000000..e260a37
--- /dev/null
+++ b/00 Base/src/redux/reducers/fruitReducer.tsx
@@ -0,0 +1,31 @@
+import { GET_ALL_FRUITS, DELETE_FRUIT, ADD_FRUIT } from './../constants';
+const initialState = {
+ fruitList: [],
+};
+export default function (state = initialState, action) {
+ switch (action.type) {
+ case GET_ALL_FRUITS: {
+ return {
+ ...state,
+ fruitList: action.payload,
+ };
+ }
+ case DELETE_FRUIT: {
+ return {
+ ...state,
+ fruitList: state.fruitList.filter((e: string) => e !== action.payload),
+ };
+ }
+ case ADD_FRUIT: {
+ return {
+ ...state,
+ fruitList: state.fruitList.concat([action.payload]),
+ };
+ }
+ default: {
+ return {
+ ...state,
+ };
+ }
+ }
+}
diff --git a/00 Base/src/redux/reducers/index.ts b/00 Base/src/redux/reducers/index.ts
new file mode 100644
index 0000000..2026315
--- /dev/null
+++ b/00 Base/src/redux/reducers/index.ts
@@ -0,0 +1,8 @@
+import { combineReducers } from 'redux';
+import fruitsReducer from './fruitReducer';
+import postReducer from './postReducer'
+
+export default combineReducers({
+ fruits: fruitsReducer,
+ posts: postReducer
+});
diff --git a/00 Base/src/redux/reducers/postReducer.tsx b/00 Base/src/redux/reducers/postReducer.tsx
new file mode 100644
index 0000000..92442cb
--- /dev/null
+++ b/00 Base/src/redux/reducers/postReducer.tsx
@@ -0,0 +1,39 @@
+import { GET_POST_FROM_API, DELETE_POST, ADD_POST } from './../constants';
+const initialState = {
+ posts: [],
+};
+export default function (state = initialState, action) {
+ switch (action.type) {
+ case GET_POST_FROM_API: {
+ return {
+ ...state,
+ posts: action.payload.data,
+ };
+ }
+ case DELETE_POST: {
+ return {
+ ...state,
+ posts: state.posts.filter((e) => e.id !== action.payload),
+ };
+ }
+
+ case ADD_POST: {
+ let tmpPost = {
+ id: Math.floor(Math.random() * 1000),
+ userId: 1,
+ title: action.payload,
+ body: action.payload,
+ };
+
+ return {
+ ...state,
+ posts: state.posts.concat([tmpPost]),
+ };
+ }
+ default: {
+ return {
+ ...state,
+ };
+ }
+ }
+}
diff --git a/00 Base/src/redux/store.js b/00 Base/src/redux/store.js
new file mode 100644
index 0000000..e7c2c33
--- /dev/null
+++ b/00 Base/src/redux/store.js
@@ -0,0 +1,12 @@
+import { createStore, applyMiddleware, compose } from 'redux';
+import thunk from 'redux-thunk';
+import rootReducer from './reducers/index';
+
+const initialState = {};
+const middleware = [thunk];
+const store=createStore(rootReducer,initialState,compose(
+ applyMiddleware(thunk),
+ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
+
+))
+export default store;
diff --git a/00 Base/src/styles.less b/00 Base/src/styles.less
new file mode 100644
index 0000000..af8d565
--- /dev/null
+++ b/00 Base/src/styles.less
@@ -0,0 +1,3 @@
+body {
+ background-color: #afafdc;
+}
diff --git a/00 Base/tsconfig.json b/00 Base/tsconfig.json
index 8a26838..3e07872 100644
--- a/00 Base/tsconfig.json
+++ b/00 Base/tsconfig.json
@@ -11,7 +11,9 @@
"allowJs": true,
"suppressImplicitAnyIndexErrors": true,
"skipLibCheck": true,
- "esModuleInterop": true
+ "esModuleInterop": true,
+ "outDir": "generated",
},
- "include": ["./src/**/*"]
+ "include": ["./src/**/*"],
+ "exclude": ["node_modules", "**/*.test.ts", "dist"]
}