├── .eslintrc.json ├── .gitignore ├── .idea ├── inspectionProfiles │ └── Project_Default.xml ├── typescript-compiler.xml └── vcs.xml ├── .prettierrc ├── Makefile ├── README.md ├── craco.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json ├── robots.txt └── settings.json ├── src ├── App.test.tsx ├── App.tsx ├── component │ ├── card │ │ ├── Card.tsx │ │ ├── CardAvatar.tsx │ │ ├── CardBody.tsx │ │ ├── CardFooter.tsx │ │ ├── CardHeader.tsx │ │ ├── CardIcon.tsx │ │ └── style │ │ │ ├── cardAvatarStyle.tsx │ │ │ ├── cardBodyStyle.tsx │ │ │ ├── cardFooterStyle.tsx │ │ │ ├── cardHeaderStyle.tsx │ │ │ ├── cardIconStyle.tsx │ │ │ └── cardStyle.tsx │ ├── customButtons │ │ ├── Button.tsx │ │ └── style │ │ │ └── buttonStyle.tsx │ ├── customInput │ │ ├── CustomInput.tsx │ │ └── style │ │ │ └── customInputStyle.tsx │ ├── customTabs │ │ ├── CustomTabs.tsx │ │ └── style │ │ │ └── customTabsStyle.ts │ ├── footer │ │ ├── Footer.tsx │ │ └── style │ │ │ └── footerStyle.tsx │ ├── grid │ │ ├── GridContainer.tsx │ │ └── GridItem.tsx │ ├── header │ │ ├── Header.tsx │ │ ├── HeaderLinks.tsx │ │ └── style │ │ │ ├── headerLinksStyle.tsx │ │ │ └── headerStyle.tsx │ ├── overlay │ │ ├── Overlay.tsx │ │ └── style │ │ │ └── overlayStyle.ts │ ├── responsiveGrid │ │ ├── ResponsiveGrid.tsx │ │ └── style │ │ │ ├── responsiveGridLayout.less │ │ │ └── responsiveGridLayoutStyle.ts │ ├── sidebar │ │ ├── Sidebar.tsx │ │ └── style │ │ │ └── sidebarStyle.tsx │ ├── snackbars │ │ ├── CustomizedSnackbar.tsx │ │ ├── Snackbar.tsx │ │ ├── SnackbarContent.tsx │ │ └── style │ │ │ └── snackbarContentStyle.tsx │ ├── status │ │ └── Status.tsx │ ├── style │ │ ├── basicsStyle.tsx │ │ ├── checkboxAdnRadioStyle.tsx │ │ ├── customCheckboxRadioSwitch.tsx │ │ ├── dropdownStyle.tsx │ │ ├── material-dashboard-react.tsx │ │ ├── modalStyle.tsx │ │ └── tooltipStyle.tsx │ ├── table │ │ ├── Table.tsx │ │ ├── TableGrid.tsx │ │ └── style │ │ │ └── tableStyle.tsx │ ├── tasks │ │ ├── Tasks.tsx │ │ └── style │ │ │ └── tasksStyle.tsx │ └── windows │ │ └── WindowContainer.tsx ├── containers │ ├── layouts │ │ ├── DashboardContainer.tsx │ │ └── box │ │ │ ├── ConfigurationFormBoxContainer.ts │ │ │ ├── ModuleInfoBoxContainer.ts │ │ │ ├── ReceiveMessagesBoxContainer.ts │ │ │ └── SendTabBoxContainer.ts │ └── views │ │ └── HomeContainer.jsx ├── favicon.ico ├── i18n │ ├── en.json │ └── it.json ├── index.css ├── index.html ├── index.tsx ├── layouts │ ├── GenericTypes.ts │ ├── Test.css │ ├── Test.tsx │ ├── box │ │ ├── AboutBox.tsx │ │ ├── AboutLibraryBox.tsx │ │ ├── AboutProgramBox.tsx │ │ ├── ConfigurationFormBox.tsx │ │ ├── ModuleInfoBox.tsx │ │ ├── ReceiveMessagesBox.tsx │ │ ├── SendTabBox.tsx │ │ ├── Types.ts │ │ ├── boxes.tsx │ │ ├── style │ │ │ └── boxStyle.ts │ │ └── utils │ │ │ └── configuration.tsx │ └── dashboard │ │ ├── Dashboard.tsx │ │ └── style │ │ └── dashboardStyle.tsx ├── logo.svg ├── manifest.json ├── react-app-env.d.ts ├── redux │ ├── actions │ │ ├── configuration.ts │ │ ├── configurationPage.ts │ │ ├── deviceMessages.ts │ │ ├── home.ts │ │ ├── index.ts │ │ ├── moduleInfo.ts │ │ ├── notifications.ts │ │ ├── resetDevice.ts │ │ ├── sendReceiveDataPage.ts │ │ ├── serverState.ts │ │ ├── subscriptionsServiceWorker.ts │ │ ├── version.ts │ │ └── webSocket.ts │ ├── config.js │ ├── logic │ │ ├── configurationGET.tsx │ │ ├── configurationPOST.tsx │ │ ├── index.ts │ │ ├── messageBroadcastPOST.tsx │ │ ├── messageFixedPOST.tsx │ │ ├── messageTransparentPOST.tsx │ │ ├── moduleInfoGET.tsx │ │ ├── resetDeviceGET.tsx │ │ ├── serverState.ts │ │ └── webSocket.tsx │ ├── reducers │ │ ├── configuration.ts │ │ ├── configurationPage.ts │ │ ├── deviceMessages.ts │ │ ├── home.ts │ │ ├── index.ts │ │ ├── moduleInfo.ts │ │ ├── notifications.tsx │ │ ├── resetDevice.ts │ │ ├── sendReceiveDataPage.ts │ │ ├── serverState.ts │ │ ├── subscriptionsServiceWorker.ts │ │ ├── version.ts │ │ └── webSocket.ts │ └── types │ │ ├── configuration.ts │ │ ├── configurationPage.ts │ │ ├── deviceMessages.ts │ │ ├── home.ts │ │ ├── index.ts │ │ ├── logic.d.ts │ │ ├── moduleInfo.ts │ │ ├── notifications.ts │ │ ├── resetDevice.ts │ │ ├── sendReceiveDataPage.ts │ │ ├── serverState.ts │ │ ├── subscriptionsServiceWorker.ts │ │ ├── version.ts │ │ └── webSocket.ts ├── resources │ └── images │ │ ├── bill.jpg │ │ ├── bill.png │ │ ├── favicon │ │ ├── android-icon-144x144.png │ │ ├── android-icon-192x192.png │ │ ├── android-icon-36x36.png │ │ ├── android-icon-48x48.png │ │ ├── android-icon-72x72.png │ │ ├── android-icon-96x96.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ └── manifest.json │ │ ├── logo.jpg │ │ ├── sidebar-solar.jpg │ │ └── textures │ │ └── pattern_type1_inverted_4x4_opacity100.png ├── routes │ ├── dashboard.tsx │ └── index.tsx ├── service-worker.js ├── serviceWorker.ts ├── settings-prod.json ├── settings.json ├── setupTests.ts ├── style │ └── app.less ├── utils │ ├── canvas │ │ ├── canvas2Image.js │ │ ├── canvg.js │ │ ├── fillFlatGradientOnReference.js │ │ ├── fillGradientOnReference.js │ │ ├── index.js │ │ └── loadImage.js │ ├── configureStore.ts │ ├── custom_function │ │ ├── deepmerge.js │ │ └── enummap.js │ ├── date │ │ └── dates.js │ ├── localStorage.js │ ├── locale │ │ ├── D3DateTimeLocales.js │ │ ├── D3NumberLocales.js │ │ ├── DSTs.js │ │ ├── GTMs.js │ │ ├── date │ │ │ ├── ca-ES.json │ │ │ ├── cs-CZ.json │ │ │ ├── de-CH.json │ │ │ ├── de-DE.json │ │ │ ├── en-CA.json │ │ │ ├── en-GB.json │ │ │ ├── en-US.json │ │ │ ├── es-ES.json │ │ │ ├── es-MX.json │ │ │ ├── fi-FI.json │ │ │ ├── fr-CA.json │ │ │ ├── fr-FR.json │ │ │ ├── he-IL.json │ │ │ ├── hu-HU.json │ │ │ ├── it-IT.json │ │ │ ├── ja-JP.json │ │ │ ├── ko-KR.json │ │ │ ├── mk-MK.json │ │ │ ├── nl-NL.json │ │ │ ├── pl-PL.json │ │ │ ├── pt-BR.json │ │ │ ├── ru-RU.json │ │ │ ├── sv-SE.json │ │ │ ├── uk-UA.json │ │ │ └── zh-CN.json │ │ ├── number │ │ │ ├── ar-001.json │ │ │ ├── ar-AE.json │ │ │ ├── ar-BH.json │ │ │ ├── ar-DJ.json │ │ │ ├── ar-DZ.json │ │ │ ├── ar-EG.json │ │ │ ├── ar-EH.json │ │ │ ├── ar-ER.json │ │ │ ├── ar-IL.json │ │ │ ├── ar-IQ.json │ │ │ ├── ar-JO.json │ │ │ ├── ar-KM.json │ │ │ ├── ar-KW.json │ │ │ ├── ar-LB.json │ │ │ ├── ar-LY.json │ │ │ ├── ar-MA.json │ │ │ ├── ar-MR.json │ │ │ ├── ar-OM.json │ │ │ ├── ar-PS.json │ │ │ ├── ar-QA.json │ │ │ ├── ar-SA.json │ │ │ ├── ar-SD.json │ │ │ ├── ar-SO.json │ │ │ ├── ar-SS.json │ │ │ ├── ar-SY.json │ │ │ ├── ar-TD.json │ │ │ ├── ar-TN.json │ │ │ ├── ar-YE.json │ │ │ ├── ca-ES.json │ │ │ ├── cs-CZ.json │ │ │ ├── de-CH.json │ │ │ ├── de-DE.json │ │ │ ├── en-CA.json │ │ │ ├── en-GB.json │ │ │ ├── en-IN.json │ │ │ ├── en-US.json │ │ │ ├── es-ES.json │ │ │ ├── es-MX.json │ │ │ ├── fi-FI.json │ │ │ ├── fr-CA.json │ │ │ ├── fr-FR.json │ │ │ ├── he-IL.json │ │ │ ├── hu-HU.json │ │ │ ├── it-IT.json │ │ │ ├── ja-JP.json │ │ │ ├── ko-KR.json │ │ │ ├── mk-MK.json │ │ │ ├── nl-NL.json │ │ │ ├── pl-PL.json │ │ │ ├── pt-BR.json │ │ │ ├── ru-RU.json │ │ │ ├── sv-SE.json │ │ │ ├── uk-UA.json │ │ │ └── zh-CN.json │ │ └── timezones.js │ ├── math │ │ ├── getReferenceHeight.js │ │ ├── guid.js │ │ └── index.js │ └── serviceWorker │ │ ├── homeScreen.js │ │ ├── subscribePush.js │ │ └── subscribeServiceWorker.js └── views │ ├── About.tsx │ ├── Configuration.tsx │ ├── Home.tsx │ ├── Intro.tsx │ ├── SendReceiveData.tsx │ └── index.js ├── tsconfig.json ├── webpack-dist.config.js └── webpack.config.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "globals": { 7 | "Atomics": "readonly", 8 | "SharedArrayBuffer": "readonly" 9 | }, 10 | "parser": "@typescript-eslint/parser", 11 | "parserOptions": { 12 | "ecmaFeatures": { 13 | "jsx": true 14 | }, 15 | "ecmaVersion": 2018, 16 | "sourceType": "module" 17 | }, 18 | "plugins": ["react", "@typescript-eslint", "prettier"], 19 | "extends": [ 20 | "plugin:react/recommended", 21 | "airbnb", 22 | // "plugin:prettier/recommended", 23 | "plugin:@typescript-eslint/eslint-recommended", 24 | "plugin:@typescript-eslint/recommended" 25 | ], 26 | "rules": { 27 | "import/extensions": [ 28 | "error", 29 | "ignorePackages", 30 | { 31 | "js": "never", 32 | "jsx": "never", 33 | "ts": "never", 34 | "tsx": "never" 35 | } 36 | ], 37 | // "prettier/prettier": "error", 38 | "@typescript-eslint/explicit-function-return-type": "off", 39 | "@typescript-eslint/no-unused-vars": "off", 40 | "@typescript-eslint/ban-ts-ignore": "off", 41 | "no-console": "off", 42 | "function-paren-newline": "off", 43 | "no-restricted-globals": "off", 44 | "@typescript-eslint/no-use-before-define": "off", 45 | "@typescript-eslint/interface-name-prefix": "off", 46 | "array-callback-return": "off", 47 | "react/jsx-filename-extension": [ 48 | 1, 49 | { "extensions": [".js", ".jsx", ".ts", ".tsx"] } 50 | ] 51 | }, 52 | "settings": { 53 | "import/resolver": { 54 | "node": { 55 | "extensions": [".js", ".jsx", ".ts", ".tsx"] 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/typescript-compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .DELETE_ON_ERROR: 2 | 3 | TIMS = $$(date +%Y%m%d%H%M%S) 4 | #export BIN := $(shell npm bin) 5 | #PATH := $(BIN):$(PATH) 6 | DIST = ./dist 7 | #BUILD = ./build 8 | LIB = ./lib 9 | EXAMPLES = ./examples 10 | PACKAGE = $(DIST)/ebyte-manager-web.js 11 | PACKAGE_MIN = $(DIST)/ebyte-manager-web.min.js 12 | PACKAGE_MIN_MAP = $(DIST)/ebyte-manager-web.min.js.map 13 | 14 | NODE_MODULE = ./node_modules 15 | 16 | clean: 17 | rm -rf $(BUILD) $(DIST) 18 | 19 | dev: 20 | webpack-dev-server --config webpack-examples.config.js 21 | 22 | prova: 23 | sed -i -e 's/no-cache/public/g' $(DIST)/index.html 24 | 25 | build: 26 | rm -rf $(DIST) 27 | mkdir $(DIST) 28 | webpack --config webpack-dist.config.js --mode=production --env.distType web --json > $(DIST)/stats.json 29 | cp ./src/manifest.json $(DIST) 30 | cp ./src/service-worker.js $(DIST) 31 | imagemin ./src/resources/images/favicon/* --out-dir=$(DIST) 32 | 33 | sed -i -e 's/resources\/images\/favicon\///g' $(DIST)/manifest.json 34 | cp ./src/index.html $(DIST) 35 | sed -i -e 's/\.\/ebyte-manager-web\.js/ebyte-manager-web\.min\.js/g' $(DIST)/index.html 36 | sed -i -e 's///-->/g' dist/index.html 38 | 39 | sed -i -e 's/22222222/'$(TIMS)'/g' $(DIST)/index.html 40 | sed -i -e 's/no-cache/public/g' $(DIST)/index.html 41 | 42 | gzip $(DIST)/*.js 43 | gzip $(DIST)/*.png 44 | gzip $(DIST)/*.jpg 45 | gzip $(DIST)/manifest.json 46 | gzip $(DIST)/service-worker.js 47 | cp ./src/favicon.ico $(DIST) 48 | gzip $(DIST)/favicon.ico 49 | sed -i 's/define\&\&define\.amd/define\&\&define\.amd\&\&\!window\.dojo\&\&\!window\.requirejs/' $(PACKAGE_MIN) 50 | 51 | mkdir $(DIST)/release 52 | cp ./src/settings-prod.json $(DIST)/release/settings.json 53 | cp $(DIST)/*.gz $(DIST)/release 54 | rm -rf $(DIST)/release/ebyte-manager-web.js* 55 | cp $(DIST)/index.html $(DIST)/release 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Front end for EByte LoRa E32 devices 2 | 3 | After npm i 4 | You must overwrite 5 | node_modules\redux-logic\definitions\logic.d.ts 6 | with 7 | src\redux\types\logic.d.ts 8 | 9 | than to start 10 | npm run dev 11 | 12 | to do the build (in linux env, you can use also windows linux env) 13 | npm run buildwp 14 | 15 | # EByte LoRa E32 Web Manager and gateway 16 | A simple web interface for the esp8266 to configure, sending and receiving LoRa messages. 17 | [![Here an example of sending message and receiving](https://img.youtube.com/vi/Jy247Nb33T4/hqdefault.jpg)](https://www.youtube.com/watch?v=Jy247Nb33T4) 18 | 19 | ## Documentation 20 | - [EByte LoRa E32 gateway: manage via REST and WebSocket (esp8266, esp32)](https://www.mischianti.org/2021/07/20/ebyte-lora-e32-gateway-manage-via-rest-and-websocket-esp8266-esp32-1/) 21 | - [EByte LoRa E32 Web Manager: description, configure and demo (esp8266, esp32)](https://www.mischianti.org/2021/07/24/ebyte-lora-e32-web-manager-description-configure-and-demo-esp8266-esp32-2/) 22 | 23 | ## API of the gateway 24 | https://documenter.getpostman.com/view/1698430/TVCcXpbi 25 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ file, options, env }) => ({ 2 | parser: file.extname === '.sss' ? 'sugarss' : false, 3 | plugins: { 4 | 'postcss-import': { root: file.dirname }, 5 | 'postcss-preset-env': options['postcss-preset-env'] ? options['postcss-preset-env'] : false, 6 | cssnano: env === 'production' ? options.cssnano : false 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 | 35 | 36 | 37 |
38 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/settings.json: -------------------------------------------------------------------------------- 1 | var settings = {"localIP":"192.168.1.127", "localRestPort":8080, "localWSPort":8081}; 2 | -------------------------------------------------------------------------------- /src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/component/card/Card.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // nodejs library that concatenates classes 3 | import classNames from 'classnames'; 4 | // nodejs library to set properties for components 5 | // import PropTypes from 'prop-types'; 6 | // @material-ui/core components 7 | import withStyles from '@material-ui/core/styles/withStyles'; 8 | // @material-ui/icons 9 | 10 | // core components 11 | import cardStyle from './style/cardStyle'; 12 | 13 | interface Props { 14 | classes: any, 15 | className: string, 16 | plain: boolean, 17 | profile: boolean, 18 | chart: boolean, 19 | 20 | } 21 | 22 | function Card({ ...props }) { 23 | const { 24 | classes, 25 | className, 26 | children, 27 | plain, 28 | profile, 29 | chart, 30 | ...rest 31 | } = props; 32 | const cardClasses = classNames({ 33 | [classes.card]: true, 34 | [classes.cardPlain]: plain, 35 | [classes.cardProfile]: profile, 36 | [classes.cardChart]: chart, 37 | [className]: className !== undefined, 38 | }); 39 | return ( 40 |
41 | {children} 42 |
43 | ); 44 | } 45 | 46 | // Card.propTypes = { 47 | // classes: PropTypes.object.isRequired, 48 | // className: PropTypes.string, 49 | // plain: PropTypes.bool, 50 | // profile: PropTypes.bool, 51 | // chart: PropTypes.bool, 52 | // }; 53 | 54 | export default withStyles(cardStyle)(Card); 55 | -------------------------------------------------------------------------------- /src/component/card/CardAvatar.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | // nodejs library that concatenates classes 3 | import classNames from "classnames"; 4 | // nodejs library to set properties for components 5 | // import PropTypes from "prop-types"; 6 | // @material-ui/core components 7 | import withStyles from "@material-ui/core/styles/withStyles"; 8 | // @material-ui/icons 9 | // core components 10 | 11 | import cardAvatarStyle from "./style/cardAvatarStyle"; 12 | 13 | interface Props { 14 | children: JSX.Element | JSX.Element[], 15 | className: string, 16 | profile: boolean, 17 | plain: boolean 18 | 19 | } 20 | 21 | function CardAvatar({ ...props }) { 22 | const { classes, children, className, plain, profile, ...rest } = props; 23 | const cardAvatarClasses = classNames({ 24 | [classes.cardAvatar]: true, 25 | [classes.cardAvatarProfile]: profile, 26 | [classes.cardAvatarPlain]: plain, 27 | [className]: className !== undefined 28 | }); 29 | return ( 30 |
31 | {children} 32 |
33 | ); 34 | } 35 | 36 | // CardAvatar.propTypes = { 37 | // children: PropTypes.node.isRequired, 38 | // className: PropTypes.string, 39 | // profile: PropTypes.bool, 40 | // plain: PropTypes.bool 41 | // }; 42 | 43 | export default withStyles(cardAvatarStyle)(CardAvatar); 44 | -------------------------------------------------------------------------------- /src/component/card/CardBody.tsx: -------------------------------------------------------------------------------- 1 | import React, {CSSProperties, ReactChildren} from "react"; 2 | // nodejs library that concatenates classes 3 | import classNames from "classnames"; 4 | // nodejs library to set properties for components 5 | // import PropTypes from "prop-types"; 6 | // @material-ui/core components 7 | import withStyles from "@material-ui/core/styles/withStyles"; 8 | // @material-ui/icons 9 | 10 | // core components 11 | import cardBodyStyle from "./style/cardBodyStyle"; 12 | 13 | interface Props { 14 | classes: any, 15 | className?: string, 16 | plain?: boolean, 17 | profile?: boolean, 18 | children: React.ReactNode[] | React.ReactNode, 19 | style?: CSSProperties 20 | } 21 | 22 | function CardBody({ ...props }: Props) { 23 | const { classes, className, children, plain, profile, ...rest } = props; 24 | let cbc: {[key: string]: any} = 25 | { 26 | [classes.cardBody]: true, 27 | [classes.cardBodyPlain]: plain, 28 | [classes.cardBodyProfile]: profile, 29 | }; 30 | if (className) { 31 | cbc[className] = className; 32 | } 33 | 34 | const cardBodyClasses = classNames(cbc); 35 | return ( 36 |
37 | {children} 38 |
39 | ); 40 | } 41 | 42 | // CardBody.propTypes = { 43 | // classes: PropTypes.object.isRequired, 44 | // className: PropTypes.string, 45 | // plain: PropTypes.bool, 46 | // profile: PropTypes.bool 47 | // }; 48 | 49 | export default withStyles(cardBodyStyle)(CardBody); 50 | -------------------------------------------------------------------------------- /src/component/card/CardFooter.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | // nodejs library that concatenates classes 3 | import classNames from "classnames"; 4 | // nodejs library to set properties for components 5 | // import PropTypes from "prop-types"; 6 | // @material-ui/core components 7 | import withStyles from "@material-ui/core/styles/withStyles"; 8 | // @material-ui/icons 9 | 10 | // core components 11 | import cardFooterStyle from "./style/cardFooterStyle"; 12 | 13 | interface Props { 14 | classes: any, 15 | className: string, 16 | plain: boolean, 17 | profile: boolean, 18 | stats: boolean, 19 | chart: boolean 20 | 21 | } 22 | 23 | function CardFooter({ ...props }) { 24 | const { 25 | classes, 26 | className, 27 | children, 28 | plain, 29 | profile, 30 | stats, 31 | chart, 32 | ...rest 33 | } = props; 34 | const cardFooterClasses = classNames({ 35 | [classes.cardFooter]: true, 36 | [classes.cardFooterPlain]: plain, 37 | [classes.cardFooterProfile]: profile, 38 | [classes.cardFooterStats]: stats, 39 | [classes.cardFooterChart]: chart, 40 | [className]: className !== undefined 41 | }); 42 | return ( 43 |
44 | {children} 45 |
46 | ); 47 | } 48 | 49 | // CardFooter.propTypes = { 50 | // classes: PropTypes.object.isRequired, 51 | // className: PropTypes.string, 52 | // plain: PropTypes.bool, 53 | // profile: PropTypes.bool, 54 | // stats: PropTypes.bool, 55 | // chart: PropTypes.bool 56 | // }; 57 | 58 | export default withStyles(cardFooterStyle)(CardFooter); 59 | -------------------------------------------------------------------------------- /src/component/card/CardHeader.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | // nodejs library that concatenates classes 3 | import classNames from "classnames"; 4 | // nodejs library to set properties for components 5 | // import PropTypes from "prop-types"; 6 | // @material-ui/core components 7 | import withStyles from "@material-ui/core/styles/withStyles"; 8 | // @material-ui/icons 9 | 10 | // core components 11 | import cardHeaderStyle from "./style/cardHeaderStyle"; 12 | import {ThemeColors} from "../../layouts/GenericTypes"; 13 | 14 | interface Props { 15 | classes: any, 16 | className?: string, 17 | color: ThemeColors 18 | children: JSX.Element | JSX.Element[] 19 | plain?: boolean, 20 | stats?: boolean, 21 | icon?: boolean 22 | } 23 | 24 | function CardHeader({ ...props }: Props) { 25 | const { 26 | classes, 27 | className, 28 | children, 29 | color, 30 | plain, 31 | stats, 32 | icon, 33 | ...rest 34 | } = props; 35 | let cn:{[key: string]: any} = { 36 | [classes.cardHeader]: true, 37 | [classes[color + "CardHeader"]]: color, 38 | [classes.cardHeaderPlain]: plain, 39 | [classes.cardHeaderStats]: stats, 40 | [classes.cardHeaderIcon]: icon 41 | }; 42 | if (className!==undefined) { 43 | cn[className] = className; 44 | } 45 | const cardHeaderClasses = classNames(cn); 46 | return ( 47 |
48 | {children} 49 |
50 | ); 51 | } 52 | 53 | // CardHeader.propTypes = { 54 | // classes: PropTypes.object.isRequired, 55 | // className: PropTypes.string, 56 | // color: PropTypes.oneOf([ 57 | // "warning", 58 | // "success", 59 | // "danger", 60 | // "info", 61 | // "primary", 62 | // "rose" 63 | // ]), 64 | // plain: PropTypes.bool, 65 | // stats: PropTypes.bool, 66 | // icon: PropTypes.bool 67 | // }; 68 | 69 | export default withStyles(cardHeaderStyle)(CardHeader); 70 | -------------------------------------------------------------------------------- /src/component/card/CardIcon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | // nodejs library that concatenates classes 3 | import classNames from "classnames"; 4 | // nodejs library to set properties for components 5 | // import PropTypes from "prop-types"; 6 | // @material-ui/core components 7 | import withStyles from "@material-ui/core/styles/withStyles"; 8 | // @material-ui/icons 9 | 10 | // core components 11 | import cardIconStyle from "./style/cardIconStyle"; 12 | import {ThemeColors} from "../../layouts/GenericTypes"; 13 | 14 | interface Props { 15 | classes: any, 16 | className?: string, 17 | color: ThemeColors 18 | children: JSX.Element | JSX.Element[] 19 | } 20 | 21 | function CardIcon({ ...props }: Props) { 22 | const { classes, className, children, color, ...rest } = props; 23 | let cn:{[key: string]: any} = { 24 | [classes.cardIcon]: true, 25 | [classes[color + "CardHeader"]]: color, 26 | }; 27 | if (className!==undefined) { 28 | cn[className] = className; 29 | } 30 | 31 | const cardIconClasses = classNames(cn); 32 | return ( 33 |
34 | {children} 35 |
36 | ); 37 | } 38 | 39 | // CardIcon.propTypes = { 40 | // classes: PropTypes.object.isRequired, 41 | // className: PropTypes.string, 42 | // color: PropTypes.oneOf([ 43 | // "warning", 44 | // "success", 45 | // "danger", 46 | // "info", 47 | // "primary", 48 | // "rose" 49 | // ]) 50 | // }; 51 | 52 | export default withStyles(cardIconStyle)(CardIcon); 53 | -------------------------------------------------------------------------------- /src/component/card/style/cardAvatarStyle.tsx: -------------------------------------------------------------------------------- 1 | import {createStyles, Theme} from "@material-ui/core"; 2 | 3 | const cardAvatarStyle = (theme: Theme) => createStyles({ 4 | cardAvatar: { 5 | "&$cardAvatarProfile img": { 6 | width: "100%", 7 | height: "auto" 8 | } 9 | }, 10 | cardAvatarProfile: { 11 | maxWidth: "130px", 12 | maxHeight: "130px", 13 | margin: "-65px auto 0", 14 | "line-height": "68px", 15 | borderRadius: "50%", 16 | overflow: "hidden", 17 | padding: "0", 18 | boxShadow: 19 | "0 16px 38px -12px rgba(0, 0, 0, 0.56), 0 4px 25px 0px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2)", 20 | "&$cardAvatarPlain": { 21 | marginTop: "0" 22 | } 23 | }, 24 | cardAvatarPlain: {} 25 | }); 26 | 27 | export default cardAvatarStyle; 28 | -------------------------------------------------------------------------------- /src/component/card/style/cardBodyStyle.tsx: -------------------------------------------------------------------------------- 1 | import {createStyles, Theme} from "@material-ui/core"; 2 | 3 | const cardBodyStyle = (theme: Theme) => createStyles({ 4 | cardBody: { 5 | padding: "0.9375rem 20px 0.9375rem 20px", 6 | // marginBottom: "1.875rem", 7 | flex: "1 1 auto", 8 | WebkitBoxFlex: 1, 9 | position: "relative", 10 | height: "100%" 11 | // height: "calc(100% - (0.9375rem + 30px))" 12 | }, 13 | cardBodyOverflow: { 14 | padding: "0.9375rem 20px 0.9375rem 20px", 15 | // marginBottom: "1.875rem", 16 | flex: "1 1 auto", 17 | WebkitBoxFlex: 1, 18 | position: "relative", 19 | height: "calc(100% - (0.9375rem + 30px))" 20 | }, 21 | cardBodyPlain: { 22 | paddingLeft: "5px", 23 | paddingRight: "5px" 24 | }, 25 | cardBodyProfile: { 26 | marginTop: "15px" 27 | } 28 | }); 29 | 30 | export default cardBodyStyle; 31 | -------------------------------------------------------------------------------- /src/component/card/style/cardFooterStyle.tsx: -------------------------------------------------------------------------------- 1 | import {createStyles, Theme} from "@material-ui/core"; 2 | 3 | const cardFooterStyle = (theme: Theme) => createStyles({ 4 | cardFooter: { 5 | padding: "0", 6 | paddingTop: "10px", 7 | margin: "0 15px 10px", 8 | borderRadius: "0", 9 | justifyContent: "space-between", 10 | alignItems: "center", 11 | display: "flex", 12 | backgroundColor: "transparent", 13 | border: "0" 14 | }, 15 | cardFooterProfile: { 16 | marginTop: "-15px" 17 | }, 18 | cardFooterPlain: { 19 | paddingLeft: "5px", 20 | paddingRight: "5px", 21 | backgroundColor: "transparent" 22 | }, 23 | cardFooterStats: { 24 | borderTop: "1px solid #eee", 25 | marginTop: "20px", 26 | "& svg": { 27 | position: "relative", 28 | top: "4px", 29 | marginRight: "3px", 30 | marginLeft: "3px", 31 | width: "16px", 32 | height: "16px" 33 | }, 34 | "& .fab,& .fas,& .far,& .fal,& .material-icons": { 35 | fontSize: "16px", 36 | position: "relative", 37 | top: "4px", 38 | marginRight: "3px", 39 | marginLeft: "3px" 40 | } 41 | }, 42 | cardFooterChart: { 43 | borderTop: "1px solid #eee" 44 | } 45 | }); 46 | 47 | export default cardFooterStyle; 48 | -------------------------------------------------------------------------------- /src/component/card/style/cardIconStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | warningCardHeader, 3 | successCardHeader, 4 | dangerCardHeader, 5 | infoCardHeader, 6 | primaryCardHeader, 7 | roseCardHeader 8 | } from "../../style/material-dashboard-react"; 9 | import {createStyles, Theme} from "@material-ui/core"; 10 | const cardIconStyle =(theme: Theme) => createStyles({ 11 | cardIcon: { 12 | "&$warningCardHeader,&$successCardHeader,&$dangerCardHeader,&$infoCardHeader,&$primaryCardHeader,&$roseCardHeader": { 13 | borderRadius: "3px", 14 | backgroundColor: "#999", 15 | padding: "15px", 16 | marginTop: "-20px", 17 | marginRight: "15px", 18 | float: "left" 19 | } 20 | }, 21 | warningCardHeader, 22 | successCardHeader, 23 | dangerCardHeader, 24 | infoCardHeader, 25 | primaryCardHeader, 26 | roseCardHeader 27 | }); 28 | 29 | export default cardIconStyle; 30 | -------------------------------------------------------------------------------- /src/component/card/style/cardStyle.tsx: -------------------------------------------------------------------------------- 1 | import {createStyles, Theme} from "@material-ui/core"; 2 | 3 | const cardStyle = (theme: Theme) => createStyles({ 4 | card: { 5 | border: '0', 6 | marginBottom: '30px', 7 | marginTop: '30px', 8 | borderRadius: '6px', 9 | color: 'rgba(0, 0, 0, 0.87)', 10 | background: '#fff', 11 | width: '100%', 12 | boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.14)', 13 | position: 'relative', 14 | display: 'flex', 15 | flexDirection: 'column', 16 | minWidth: '0', 17 | wordWrap: 'break-word', 18 | fontSize: '.875rem', 19 | height: 'calc(100% - 30px)', 20 | }, 21 | cardPlain: { 22 | background: 'transparent', 23 | boxShadow: 'none', 24 | }, 25 | cardProfile: { 26 | marginTop: '30px', 27 | textAlign: 'center', 28 | }, 29 | cardChart: { 30 | '& p': { 31 | marginTop: '0px', 32 | paddingTop: '0px', 33 | }, 34 | }, 35 | }); 36 | 37 | export default cardStyle; 38 | -------------------------------------------------------------------------------- /src/component/customButtons/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // nodejs library that concatenates classes 3 | import classNames from 'classnames'; 4 | // nodejs library to set properties for components 5 | // import PropTypes from 'prop-types'; 6 | 7 | // material-ui components 8 | import withStyles from '@material-ui/core/styles/withStyles'; 9 | import Button from '@material-ui/core/Button'; 10 | 11 | import buttonStyle from './style/buttonStyle'; 12 | 13 | interface Props { 14 | classes: any, 15 | color: string, // PropTypes.oneOf(['primary','info','success','warning','danger','rose','white','transparent',]), 16 | size?: string,// PropTypes.oneOf(['sm', 'lg']), 17 | simple?: boolean, 18 | round?: boolean, 19 | disabled?: boolean, 20 | block?: boolean, 21 | link?: string, 22 | justIcon?: boolean, 23 | className?: string, 24 | // use this to pass the classes props from Material-UI 25 | muiClasses?: any, 26 | children?: any, 27 | href?: string, 28 | buttonRef?: any, 29 | onClick?: (evt: any) => void, 30 | startIcon?: React.ReactNode, 31 | endIcon?: React.ReactNode, 32 | type?: "button" | "reset" | "submit" | undefined 33 | } 34 | 35 | function RegularButton({ ...props }: Props) { 36 | const { 37 | classes, 38 | color, 39 | round, 40 | children, 41 | disabled, 42 | simple, 43 | size, 44 | block, 45 | link, 46 | justIcon, 47 | className, 48 | muiClasses, 49 | ...rest 50 | } = props; 51 | interface Icn { 52 | [key: string]: any 53 | }; 54 | let cn: Icn = { 55 | [classes.button]: true, 56 | // [classes[size]]: size, 57 | [classes[color]]: color, 58 | [classes.round]: round, 59 | [classes.disabled]: disabled, 60 | [classes.simple]: simple, 61 | [classes.block]: block, 62 | [classes.link]: link, 63 | [classes.justIcon]: justIcon, 64 | 65 | }; 66 | if (className) { 67 | cn[className] = className; 68 | } 69 | const btnClasses = classNames(cn); 70 | return ( 71 | 74 | ); 75 | } 76 | 77 | // RegularButton.propTypes = { 78 | // classes: PropTypes.object.isRequired, 79 | // color: PropTypes.oneOf([ 80 | // 'primary', 81 | // 'info', 82 | // 'success', 83 | // 'warning', 84 | // 'danger', 85 | // 'rose', 86 | // 'white', 87 | // 'transparent', 88 | // ]), 89 | // size: PropTypes.oneOf(['sm', 'lg']), 90 | // simple: PropTypes.bool, 91 | // round: PropTypes.bool, 92 | // disabled: PropTypes.bool, 93 | // block: PropTypes.bool, 94 | // link: PropTypes.bool, 95 | // justIcon: PropTypes.bool, 96 | // className: PropTypes.string, 97 | // // use this to pass the classes props from Material-UI 98 | // muiClasses: PropTypes.object, 99 | // }; 100 | 101 | export default withStyles(buttonStyle)(RegularButton); 102 | -------------------------------------------------------------------------------- /src/component/customInput/CustomInput.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classNames from 'classnames'; 3 | import PropTypes from 'prop-types'; 4 | // @material-ui/core components 5 | import withStyles from '@material-ui/core/styles/withStyles'; 6 | import FormControl from '@material-ui/core/FormControl'; 7 | import InputLabel from '@material-ui/core/InputLabel'; 8 | import Input from '@material-ui/core/Input'; 9 | // @material-ui/icons 10 | import Clear from '@material-ui/icons/Clear'; 11 | import Check from '@material-ui/icons/Check'; 12 | // core components 13 | import customInputStyle from './style/customInputStyle'; 14 | 15 | interface Props { 16 | classes: any, 17 | labelText: JSX.Element | string, 18 | labelProps: any, 19 | id: string, 20 | inputProps: any, 21 | formControlProps: any, 22 | error: boolean, 23 | success: boolean 24 | } 25 | 26 | function CustomInput({ ...props }: Props) { 27 | const { 28 | classes, 29 | formControlProps, 30 | labelText, 31 | id, 32 | labelProps, 33 | inputProps, 34 | error, 35 | success 36 | } = props; 37 | 38 | const labelClasses = classNames({ 39 | [` ${classes.labelRootError}`]: error, 40 | [` ${classes.labelRootSuccess}`]: success && !error 41 | }); 42 | const underlineClasses = classNames({ 43 | [classes.underlineError]: error, 44 | [classes.underlineSuccess]: success && !error, 45 | [classes.underline]: true 46 | }); 47 | const marginTop = classNames({ 48 | [classes.marginTop]: labelText === undefined 49 | }); 50 | return ( 51 | 55 | {labelText !== undefined ? ( 56 | 61 | {labelText} 62 | 63 | ) : null} 64 | 73 | {error ? ( 74 | 75 | ) : success ? ( 76 | 77 | ) : null} 78 | 79 | ); 80 | } 81 | 82 | // CustomInput.propTypes = { 83 | // classes: PropTypes.object.isRequired, 84 | // labelText: PropTypes.node, 85 | // labelProps: PropTypes.object, 86 | // id: PropTypes.string, 87 | // inputProps: PropTypes.object, 88 | // formControlProps: PropTypes.object, 89 | // error: PropTypes.bool, 90 | // success: PropTypes.bool 91 | // }; 92 | 93 | export default withStyles(customInputStyle)(CustomInput); 94 | -------------------------------------------------------------------------------- /src/component/customInput/style/customInputStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | primaryColor, 3 | dangerColor, 4 | successColor, 5 | defaultFont 6 | } from '../../style/material-dashboard-react'; 7 | import {createStyles, Theme} from "@material-ui/core"; 8 | 9 | const customInputStyle =(theme: Theme) => createStyles({ 10 | disabled: { 11 | '&:before': { 12 | backgroundColor: 'transparent !important' 13 | } 14 | }, 15 | underline: { 16 | '&:hover:not($disabled):before,&:before': { 17 | borderColor: '#D2D2D2 !important', 18 | borderWidth: '1px !important' 19 | }, 20 | '&:after': { 21 | borderColor: primaryColor 22 | } 23 | }, 24 | underlineError: { 25 | '&:after': { 26 | borderColor: dangerColor 27 | } 28 | }, 29 | underlineSuccess: { 30 | '&:after': { 31 | borderColor: successColor 32 | } 33 | }, 34 | labelRoot: { 35 | ...defaultFont, 36 | color: '#AAAAAA !important', 37 | fontWeight: 400, 38 | fontSize: '14px', 39 | lineHeight: '1.42857' 40 | }, 41 | labelRootError: { 42 | color: dangerColor 43 | }, 44 | labelRootSuccess: { 45 | color: successColor 46 | }, 47 | feedback: { 48 | position: 'absolute', 49 | top: '18px', 50 | right: '0', 51 | zIndex: 2, 52 | display: 'block', 53 | width: '24px', 54 | height: '24px', 55 | textAlign: 'center', 56 | pointerEvents: 'none' 57 | }, 58 | marginTop: { 59 | marginTop: '16px' 60 | }, 61 | formControl: { 62 | paddingBottom: '10px', 63 | margin: '27px 0 0 0', 64 | position: 'relative' 65 | } 66 | }); 67 | 68 | export default customInputStyle; 69 | -------------------------------------------------------------------------------- /src/component/customTabs/style/customTabsStyle.ts: -------------------------------------------------------------------------------- 1 | import { hexToRgb, whiteColor } from "../../style/material-dashboard-react"; 2 | import {createStyles, Theme} from "@material-ui/core"; 3 | 4 | const customTabsStyle = (theme: Theme) => createStyles({ 5 | cardTitle: { 6 | float: "left", 7 | padding: "10px 10px 10px 0px", 8 | lineHeight: "24px" 9 | }, 10 | cardTitleRTL: { 11 | float: "right", 12 | padding: "10px 0px 10px 10px !important" 13 | }, 14 | displayNone: { 15 | display: "none !important" 16 | }, 17 | tabsRoot: { 18 | minHeight: "unset !important", 19 | overflowX: "visible", 20 | "& $tabRootButton": { 21 | fontSize: "0.875rem" 22 | } 23 | }, 24 | tabRootButton: { 25 | minHeight: "unset !important", 26 | minWidth: "unset !important", 27 | width: "unset !important", 28 | height: "unset !important", 29 | maxWidth: "unset !important", 30 | maxHeight: "unset !important", 31 | padding: "10px 15px", 32 | borderRadius: "3px", 33 | lineHeight: "24px", 34 | border: "0 !important", 35 | color: whiteColor + " !important", 36 | marginLeft: "4px", 37 | "&:last-child": { 38 | marginLeft: "0px" 39 | } 40 | }, 41 | tabLabelContainer: { 42 | padding: "0px" 43 | }, 44 | tabLabel: { 45 | fontWeight: 500, 46 | fontSize: "12px" 47 | }, 48 | tabSelected: { 49 | backgroundColor: "rgba(" + hexToRgb(whiteColor) + ", 0.2)", 50 | transition: "0.2s background-color 0.1s" 51 | }, 52 | tabWrapper: { 53 | display: "inline-block", 54 | minHeight: "unset !important", 55 | minWidth: "unset !important", 56 | width: "unset !important", 57 | height: "unset !important", 58 | maxWidth: "unset !important", 59 | maxHeight: "unset !important", 60 | "& > svg,& > .material-icons": { 61 | verticalAlign: "middle", 62 | margin: "-1px 5px 0 0" 63 | } 64 | } 65 | }); 66 | 67 | export default customTabsStyle; 68 | -------------------------------------------------------------------------------- /src/component/footer/Footer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | // import PropTypes from "prop-types"; 3 | // @material-ui/core components 4 | import withStyles from "@material-ui/core/styles/withStyles"; 5 | import ListItem from "@material-ui/core/ListItem"; 6 | import List from "@material-ui/core/List"; 7 | // core components 8 | import footerStyle from "./style/footerStyle"; 9 | 10 | interface Props { 11 | classes: any 12 | } 13 | 14 | function Footer({ ...props }: Props) { 15 | const { classes } = props; 16 | return ( 17 | 54 | ); 55 | } 56 | 57 | // Footer.propTypes = { 58 | // classes: PropTypes.object.isRequired 59 | // }; 60 | 61 | export default withStyles(footerStyle)(Footer); 62 | -------------------------------------------------------------------------------- /src/component/footer/style/footerStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | defaultFont, 3 | container, 4 | primaryColor 5 | } from "../../../component/style/material-dashboard-react"; 6 | import {createStyles, Theme} from "@material-ui/core"; 7 | 8 | const footerStyle =(theme: Theme) => createStyles( { 9 | block: { 10 | color: "inherit", 11 | padding: "5px", 12 | textTransform: "uppercase", 13 | borderRadius: "3px", 14 | textDecoration: "none", 15 | position: "relative", 16 | display: "block", 17 | ...defaultFont, 18 | fontWeight: 500, 19 | fontSize: "12px" 20 | }, 21 | left: { 22 | float: "left!important" as "left", 23 | display: "block" 24 | }, 25 | right: { 26 | // padding: "5px 0", 27 | margin: "0", 28 | fontSize: "14px", 29 | float: "right!important" as "right" 30 | }, 31 | footer: { 32 | bottom: "0", 33 | borderTop: "1px solid #e7e7e7", 34 | padding: "5px 0", 35 | ...defaultFont 36 | }, 37 | container, 38 | a: { 39 | color: primaryColor, 40 | textDecoration: "none", 41 | backgroundColor: "transparent" 42 | }, 43 | list: { 44 | marginBottom: "0", 45 | padding: "0", 46 | marginTop: "0" 47 | }, 48 | inlineBlock: { 49 | display: "inline-block", 50 | padding: "0px", 51 | width: "auto" 52 | } 53 | }); 54 | export default footerStyle; 55 | -------------------------------------------------------------------------------- /src/component/grid/GridContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // @material-ui/core components 3 | import withStyles from '@material-ui/core/styles/withStyles'; 4 | import Grid, {GridSpacing} from '@material-ui/core/Grid'; 5 | import {createStyles, Theme} from "@material-ui/core"; 6 | 7 | const style =(theme: Theme) => createStyles({ 8 | grid: { 9 | margin: '0 -15px !important', 10 | width: 'unset', 11 | } 12 | }); 13 | 14 | interface Props { 15 | classes: any, 16 | spacing?: GridSpacing, 17 | children: React.ReactElement | React.ReactElement[] 18 | } 19 | 20 | function GridContainer(props: Props) { 21 | const { classes, children, ...rest } = props; 22 | return ( 23 | 24 | {children} 25 | 26 | ); 27 | } 28 | 29 | export default withStyles(style)(GridContainer); 30 | -------------------------------------------------------------------------------- /src/component/grid/GridItem.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // @material-ui/core components 3 | import withStyles from '@material-ui/core/styles/withStyles'; 4 | import Grid from '@material-ui/core/Grid'; 5 | 6 | const style = { 7 | grid: { 8 | padding: '0 15px !important' 9 | } 10 | }; 11 | 12 | function GridItem({ ...props }) { 13 | const { classes, children, ...rest } = props; 14 | return ( 15 | 16 | {children} 17 | 18 | ); 19 | } 20 | 21 | export default withStyles(style)(GridItem); 22 | -------------------------------------------------------------------------------- /src/component/header/style/headerLinksStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | defaultFont, 3 | dangerColor 4 | } from "../../../component/style/material-dashboard-react"; 5 | 6 | import dropdownStyle from "../../../component/style/dropdownStyle"; 7 | import {createStyles, Theme} from "@material-ui/core"; 8 | 9 | const headerLinksStyle =(theme: Theme) => createStyles({ 10 | ...dropdownStyle(theme), 11 | search: { 12 | "& > div": { 13 | marginTop: "0" 14 | }, 15 | [theme.breakpoints.down("sm")]: { 16 | margin: "10px 15px !important", 17 | float: "none !important", 18 | paddingTop: "1px", 19 | paddingBottom: "1px", 20 | padding: "0!important", 21 | width: "60%", 22 | marginTop: "40px", 23 | "& input": { 24 | color: "#FFFFFF" 25 | } 26 | } 27 | }, 28 | linkText: { 29 | zIndex: 4, 30 | ...defaultFont, 31 | fontSize: "14px", 32 | margin: "0px" 33 | }, 34 | buttonLink: { 35 | [theme.breakpoints.down("sm")]: { 36 | display: "flex", 37 | margin: "10px 15px 0", 38 | width: "-webkit-fill-available", 39 | "& svg": { 40 | width: "24px", 41 | height: "30px", 42 | marginRight: "15px", 43 | marginLeft: "-15px" 44 | }, 45 | "& .fab,& .fas,& .far,& .fal,& .material-icons": { 46 | fontSize: "24px", 47 | lineHeight: "30px", 48 | width: "24px", 49 | height: "30px", 50 | marginRight: "15px", 51 | marginLeft: "-15px" 52 | }, 53 | "& > span": { 54 | justifyContent: "flex-start", 55 | width: "100%" 56 | } 57 | } 58 | }, 59 | searchButton: { 60 | [theme.breakpoints.down("sm")]: { 61 | top: "-50px !important", 62 | marginRight: "22px", 63 | float: "right" 64 | } 65 | }, 66 | margin: { 67 | zIndex: 4, 68 | margin: "0" 69 | }, 70 | searchIcon: { 71 | width: "17px", 72 | zIndex: 4 73 | }, 74 | notifications: { 75 | zIndex: 4, 76 | [theme.breakpoints.up("md")]: { 77 | position: "absolute", 78 | top: "2px", 79 | border: "1px solid #FFF", 80 | right: "4px", 81 | fontSize: "9px", 82 | background: dangerColor, 83 | color: "#FFFFFF", 84 | minWidth: "16px", 85 | height: "16px", 86 | borderRadius: "10px", 87 | textAlign: "center", 88 | lineHeight: "16px", 89 | verticalAlign: "middle", 90 | display: "block" 91 | }, 92 | [theme.breakpoints.down("sm")]: { 93 | ...defaultFont, 94 | fontSize: "14px", 95 | marginRight: "8px" 96 | } 97 | }, 98 | manager: { 99 | [theme.breakpoints.down("sm")]: { 100 | width: "100%" 101 | }, 102 | display: "inline-block" 103 | }, 104 | searchWrapper: { 105 | [theme.breakpoints.down("sm")]: { 106 | width: "-webkit-fill-available", 107 | margin: "10px 15px 0" 108 | }, 109 | display: "inline-block" 110 | } 111 | }); 112 | 113 | export default headerLinksStyle; 114 | -------------------------------------------------------------------------------- /src/component/header/style/headerStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | container, 3 | defaultFont, 4 | primaryColor, 5 | defaultBoxShadow, 6 | infoColor, 7 | successColor, 8 | warningColor, 9 | dangerColor 10 | } from "../../../component/style/material-dashboard-react"; 11 | import {createStyles, Theme} from "@material-ui/core"; 12 | 13 | const headerStyle = (theme: Theme) => createStyles({ 14 | appBar: { 15 | backgroundColor: "transparent", 16 | boxShadow: "none", 17 | borderBottom: "0", 18 | marginBottom: "0", 19 | position: "absolute", 20 | width: "100%", 21 | paddingTop: "10px", 22 | zIndex: 1029, 23 | color: "#555555", 24 | border: "0", 25 | borderRadius: "3px", 26 | padding: "10px 0", 27 | transition: "all 150ms ease 0s", 28 | minHeight: "50px", 29 | display: "block" 30 | }, 31 | container: { 32 | ...container, 33 | minHeight: "50px" 34 | }, 35 | flex: { 36 | flex: 1 37 | }, 38 | title: { 39 | ...defaultFont, 40 | lineHeight: "30px", 41 | fontSize: "18px", 42 | borderRadius: "3px", 43 | textTransform: "none", 44 | color: "inherit", 45 | margin: "0", 46 | "&:hover,&:focus": { 47 | background: "transparent" 48 | } 49 | }, 50 | appResponsive: { 51 | top: "8px" 52 | }, 53 | primary: { 54 | backgroundColor: primaryColor, 55 | color: "#FFFFFF", 56 | ...defaultBoxShadow 57 | }, 58 | info: { 59 | backgroundColor: infoColor, 60 | color: "#FFFFFF", 61 | ...defaultBoxShadow 62 | }, 63 | success: { 64 | backgroundColor: successColor, 65 | color: "#FFFFFF", 66 | ...defaultBoxShadow 67 | }, 68 | warning: { 69 | backgroundColor: warningColor, 70 | color: "#FFFFFF", 71 | ...defaultBoxShadow 72 | }, 73 | danger: { 74 | backgroundColor: dangerColor, 75 | color: "#FFFFFF", 76 | ...defaultBoxShadow 77 | } 78 | }); 79 | 80 | export default headerStyle; 81 | -------------------------------------------------------------------------------- /src/component/overlay/Overlay.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import withStyles from '@material-ui/core/styles/withStyles'; 5 | import CircularProgress from '@material-ui/core/CircularProgress'; 6 | import overlayStyle from './style/overlayStyle'; 7 | import * as colorMod from '../style/material-dashboard-react'; 8 | 9 | interface Props { 10 | classes: any, 11 | visible: boolean 12 | 13 | } 14 | 15 | const Overlay = ({ ...props }: Props) => { 16 | const { 17 | classes, 18 | visible 19 | } = props; 20 | 21 | return ( 22 | (visible)?
23 |
24 |
:null 25 | ); 26 | }; 27 | 28 | // Overlay.propTypes = { 29 | // classes: PropTypes.object.isRequired, 30 | // visible: PropTypes.bool 31 | // }; 32 | Overlay.defaultProps = { 33 | visible: false 34 | }; 35 | 36 | export default withStyles(overlayStyle)(Overlay); 37 | -------------------------------------------------------------------------------- /src/component/overlay/style/overlayStyle.ts: -------------------------------------------------------------------------------- 1 | import {createStyles, Theme} from "@material-ui/core"; 2 | 3 | const overlayStyle =(theme: Theme) => createStyles({ 4 | backGround: { 5 | position: 'fixed', /* Sit on top of the page content */ 6 | // display: 'none', /* Hidden by default */ 7 | width: '100%', /* Full width (cover the whole page) */ 8 | height: '100%', /* Full height (cover the whole page) */ 9 | top: 0, 10 | left: 0, 11 | right: 0, 12 | bottom: 0, 13 | backgroundColor: 'rgba(0,0,0,0.5)', /* Black background with opacity */ 14 | zIndex: 2000, /* Specify a stack order in case you're using a different order for other */ 15 | cursor: 'pointer' /* Add a pointer on hover */ 16 | 17 | }, 18 | progress: { 19 | margin: 0, 20 | position: 'absolute', 21 | top: '50%', 22 | left: '50%', 23 | transform: 'translate(-50%, -50%)' 24 | } 25 | }); 26 | 27 | export default overlayStyle; 28 | -------------------------------------------------------------------------------- /src/component/responsiveGrid/style/responsiveGridLayout.less: -------------------------------------------------------------------------------- 1 | .react-grid-layout { 2 | position: relative; 3 | 4 | transition: height 200ms ease; 5 | 6 | min-height: calc(100vh - 30px); 7 | 8 | background-color: transparent; 9 | 10 | } 11 | .react-grid-item { 12 | transition: all 200ms ease; 13 | transition-property: left, top; 14 | //background-color: bisque; 15 | overflow-y: hidden; 16 | } 17 | .react-grid-item.cssTransforms { 18 | transition-property: transform; 19 | } 20 | 21 | .react-grid-item.resizing { 22 | z-index: 1; 23 | will-change: width, height; 24 | } 25 | 26 | .react-grid-item.react-draggable-dragging { 27 | transition: none; 28 | z-index: 3; 29 | will-change: transform; 30 | } 31 | 32 | .react-grid-item.react-grid-placeholder { 33 | background: red; 34 | opacity: 0.2; 35 | transition-duration: 100ms; 36 | z-index: 2; 37 | -webkit-user-select: none; 38 | -moz-user-select: none; 39 | -ms-user-select: none; 40 | -o-user-select: none; 41 | user-select: none; 42 | } 43 | 44 | .react-grid-item > .react-resizable-handle { 45 | position: absolute; 46 | width: 20px; 47 | height: 20px; 48 | bottom: 0; 49 | right: 0; 50 | background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4='); 51 | background-position: bottom right; 52 | padding: 0 3px 3px 0; 53 | background-repeat: no-repeat; 54 | background-origin: content-box; 55 | box-sizing: border-box; 56 | cursor: se-resize; 57 | } 58 | -------------------------------------------------------------------------------- /src/component/responsiveGrid/style/responsiveGridLayoutStyle.ts: -------------------------------------------------------------------------------- 1 | import {createStyles, Theme} from "@material-ui/core"; 2 | 3 | const responsiveGridLayoutStyle = (theme: Theme) => createStyles({ 4 | fab: { 5 | position: 'fixed', 6 | bottom: theme.spacing(3), 7 | right: theme.spacing(2), 8 | } 9 | }); 10 | 11 | export default responsiveGridLayoutStyle; 12 | -------------------------------------------------------------------------------- /src/component/snackbars/SnackbarContent.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import classNames from 'classnames'; 4 | // @material-ui/core components 5 | import withStyles from '@material-ui/core/styles/withStyles'; 6 | import Snack from '@material-ui/core/SnackbarContent'; 7 | import IconButton from '@material-ui/core/IconButton'; 8 | // @material-ui/icons 9 | import Close from '@material-ui/icons/Close'; 10 | // core components 11 | import snackbarContentStyle from './style/snackbarContentStyle'; 12 | import {Function} from "@babel/types"; 13 | 14 | interface Props { 15 | message: JSX.Element | string, 16 | classes: any, 17 | color: string, //PropTypes.oneOf(['info', 'success', 'warning', 'danger', 'primary']), 18 | close: boolean, 19 | icon: any, 20 | onClose: Function 21 | } 22 | 23 | function SnackbarContent({ ...props }:Props) { 24 | const { 25 | classes, message, color, close, icon, onClose 26 | } = props; 27 | let action: JSX.Element[] = []; 28 | const messageClasses = classNames({ 29 | [classes.iconMessage]: icon !== undefined 30 | }); 31 | if (close !== undefined) { 32 | action = [ 33 | 39 | 40 | 41 | ]; 42 | } 43 | return ( 44 | 48 | {icon !== undefined ? : null} 49 | {message} 50 | 51 | )} 52 | classes={{ 53 | root: `${classes.root} ${classes[color]}`, 54 | message: classes.message 55 | }} 56 | action={action} 57 | /> 58 | ); 59 | } 60 | 61 | // SnackbarContent.propTypes = { 62 | // classes: PropTypes.object.isRequired, 63 | // message: PropTypes.node.isRequired, 64 | // color: PropTypes.oneOf(['info', 'success', 'warning', 'danger', 'primary']), 65 | // close: PropTypes.bool, 66 | // icon: PropTypes.func, 67 | // onClose: PropTypes.func 68 | // }; 69 | // 70 | export default withStyles(snackbarContentStyle)(SnackbarContent); 71 | -------------------------------------------------------------------------------- /src/component/snackbars/style/snackbarContentStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | defaultFont, 3 | primaryBoxShadow, 4 | infoBoxShadow, 5 | successBoxShadow, 6 | warningBoxShadow, 7 | dangerBoxShadow, 8 | roseBoxShadow 9 | } from "../../style/material-dashboard-react"; 10 | import {createStyles, Theme} from "@material-ui/core"; 11 | 12 | const snackbarContentStyle = (theme: Theme) => createStyles({ 13 | root: { 14 | ...defaultFont, 15 | flexWrap: "unset", 16 | position: "relative", 17 | padding: "20px 15px", 18 | lineHeight: "20px", 19 | marginBottom: "20px", 20 | fontSize: "14px", 21 | backgroundColor: "white", 22 | color: "#555555", 23 | borderRadius: "3px", 24 | boxShadow: 25 | "0 12px 20px -10px rgba(255, 255, 255, 0.28), 0 4px 20px 0px rgba(0, 0, 0, 0.12), 0 7px 8px -5px rgba(255, 255, 255, 0.2)" 26 | }, 27 | top20: { 28 | top: "20px" 29 | }, 30 | top40: { 31 | top: "40px" 32 | }, 33 | info: { 34 | backgroundColor: "#00d3ee", 35 | color: "#ffffff", 36 | ...infoBoxShadow 37 | }, 38 | success: { 39 | backgroundColor: "#5cb860", 40 | color: "#ffffff", 41 | ...successBoxShadow 42 | }, 43 | warning: { 44 | backgroundColor: "#ffa21a", 45 | color: "#ffffff", 46 | ...warningBoxShadow 47 | }, 48 | danger: { 49 | backgroundColor: "#f55a4e", 50 | color: "#ffffff", 51 | ...dangerBoxShadow 52 | }, 53 | primary: { 54 | backgroundColor: "#af2cc5", 55 | color: "#ffffff", 56 | ...primaryBoxShadow 57 | }, 58 | rose: { 59 | backgroundColor: "#eb3573", 60 | color: "#ffffff", 61 | ...roseBoxShadow 62 | }, 63 | message: { 64 | padding: "0", 65 | display: "block", 66 | maxWidth: "89%" 67 | }, 68 | close: { 69 | width: "11px", 70 | height: "11px" 71 | }, 72 | iconButton: { 73 | width: "24px", 74 | height: "24px", 75 | padding: "0px" 76 | }, 77 | icon: { 78 | display: "block", 79 | left: "15px", 80 | position: "absolute", 81 | top: "50%", 82 | marginTop: "-15px", 83 | width: "30px", 84 | height: "30px" 85 | }, 86 | infoIcon: { 87 | color: "#00d3ee" 88 | }, 89 | successIcon: { 90 | color: "#5cb860" 91 | }, 92 | warningIcon: { 93 | color: "#ffa21a" 94 | }, 95 | dangerIcon: { 96 | color: "#f55a4e" 97 | }, 98 | primaryIcon: { 99 | color: "#af2cc5" 100 | }, 101 | roseIcon: { 102 | color: "#eb3573" 103 | }, 104 | iconMessage: { 105 | paddingLeft: "50px", 106 | display: "block" 107 | } 108 | }); 109 | 110 | export default snackbarContentStyle; 111 | -------------------------------------------------------------------------------- /src/component/status/Status.tsx: -------------------------------------------------------------------------------- 1 | import SentimentSatisfied from '@material-ui/icons/SentimentSatisfied'; 2 | import SentimentDissatisfied from '@material-ui/icons/SentimentDissatisfied'; 3 | import SentimentVeryDissatisfied from '@material-ui/icons/SentimentVeryDissatisfied'; 4 | 5 | import React from 'react'; 6 | import withStyles from '@material-ui/core/styles/withStyles'; 7 | // import PropTypes from 'prop-types'; 8 | import boxStyle from '../../layouts/box/style/boxStyle'; 9 | import Button from '../customButtons/Button'; 10 | 11 | interface Props { 12 | classes: any, 13 | status: 'ok' | 'no' | 'warning' 14 | } 15 | 16 | function Status({ ...props }: Props) { 17 | const { classes, status } = props; 18 | 19 | const getElement = (status: 'ok' | 'no' | 'warning') => { 20 | switch (status) { 21 | case 'ok': 22 | return ( 23 | 26 | ); 27 | case 'no': 28 | return ( 29 | 32 | ); 33 | case 'warning': 34 | return ( 35 | 38 | ); 39 | } 40 | }; 41 | 42 | 43 | return getElement(status); 44 | } 45 | 46 | // Status.propTypes = { 47 | // classes: PropTypes.object.isRequired, 48 | // status: PropTypes.oneOf(['ok', 'no', 'warning']).isRequired 49 | // }; 50 | 51 | export default withStyles(boxStyle)(Status); 52 | -------------------------------------------------------------------------------- /src/component/style/basicsStyle.tsx: -------------------------------------------------------------------------------- 1 | import { container, title } from './material-dashboard-react'; 2 | import customCheckboxRadioSwitch from './customCheckboxRadioSwitch'; 3 | import modalStyle from './modalStyle'; 4 | import {createStyles, Theme} from "@material-ui/core"; 5 | 6 | const basicsStyle = (theme: Theme) => createStyles({ 7 | sections: { 8 | padding: '70px 0' 9 | }, 10 | container, 11 | title: { 12 | ...title, 13 | marginTop: '30px', 14 | minHeight: '32px', 15 | textDecoration: 'none' 16 | }, 17 | space50: { 18 | height: '50px', 19 | display: 'block' 20 | }, 21 | space70: { 22 | height: '70px', 23 | display: 'block' 24 | }, 25 | icons: { 26 | width: '17px', 27 | height: '17px', 28 | color: '#FFFFFF' 29 | }, 30 | 31 | textField: { 32 | flexBasis: 200, 33 | width: '100%' 34 | }, 35 | 36 | ...customCheckboxRadioSwitch, 37 | ...modalStyle 38 | }); 39 | 40 | export default basicsStyle; 41 | -------------------------------------------------------------------------------- /src/component/style/checkboxAdnRadioStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | primaryColor, 3 | blackColor, 4 | hexToRgb 5 | } from './material-dashboard-react' 6 | 7 | const checkboxAdnRadioStyle = { 8 | root: { 9 | padding: "13px" 10 | }, 11 | checked: { 12 | color: primaryColor[0] + "!important" 13 | }, 14 | checkedIcon: { 15 | width: "20px", 16 | height: "20px", 17 | border: "1px solid rgba(" + hexToRgb(blackColor) + ", .54)", 18 | borderRadius: "3px", 19 | boxSizing: "content-box" 20 | }, 21 | uncheckedIcon: { 22 | width: "0px", 23 | height: "0px", 24 | padding: "10px", 25 | border: "1px solid rgba(" + hexToRgb(blackColor) + ", .54)", 26 | borderRadius: "3px" 27 | }, 28 | radio: { 29 | color: primaryColor[0] + "!important" 30 | }, 31 | radioChecked: { 32 | width: "20px", 33 | height: "20px", 34 | border: "1px solid " + primaryColor[0], 35 | borderRadius: "50%", 36 | boxSizing: "content-box" 37 | }, 38 | radioUnchecked: { 39 | width: "0px", 40 | height: "0px", 41 | padding: "10px", 42 | border: "1px solid rgba(" + hexToRgb(blackColor) + ", .54)", 43 | borderRadius: "50%" 44 | } 45 | }; 46 | 47 | export default checkboxAdnRadioStyle; 48 | -------------------------------------------------------------------------------- /src/component/style/modalStyle.tsx: -------------------------------------------------------------------------------- 1 | const modalStyle = { 2 | modal: { 3 | borderRadius: '6px' 4 | }, 5 | modalHeader: { 6 | borderBottom: 'none', 7 | paddingTop: '24px', 8 | paddingRight: '24px', 9 | paddingBottom: '0', 10 | paddingLeft: '24px', 11 | minHeight: '16.43px' 12 | }, 13 | modalTitle: { 14 | margin: '0', 15 | lineHeight: '1.42857143' 16 | }, 17 | modalCloseButton: { 18 | color: '#999999', 19 | marginTop: '-12px', 20 | WebkitAppearance: 'none' as any, 21 | padding: '0', 22 | cursor: 'pointer', 23 | background: '0 0', 24 | border: '0', 25 | fontSize: 'inherit', 26 | opacity: '.9', 27 | textShadow: 'none', 28 | fontWeight: 700, 29 | lineHeight: '1', 30 | float: 'right' as any 31 | }, 32 | modalClose: { 33 | width: '16px', 34 | height: '16px' 35 | }, 36 | modalBody: { 37 | paddingTop: '24px', 38 | paddingRight: '24px', 39 | paddingBottom: '16px', 40 | paddingLeft: '24px', 41 | position: 'relative' as any 42 | }, 43 | modalFooter: { 44 | padding: '15px', 45 | textAlign: 'right' as any, 46 | paddingTop: '0', 47 | margin: '0' 48 | }, 49 | modalFooterCenter: { 50 | marginLeft: 'auto', 51 | marginRight: 'auto' 52 | } 53 | }; 54 | 55 | export default modalStyle; 56 | -------------------------------------------------------------------------------- /src/component/style/tooltipStyle.tsx: -------------------------------------------------------------------------------- 1 | import { blackColor, hexToRgb } from './material-dashboard-react'; 2 | 3 | const tooltipStyle = { 4 | tooltip: { 5 | padding: "10px 15px", 6 | minWidth: "130px", 7 | lineHeight: "1.7em", 8 | border: "none", 9 | borderRadius: "3px", 10 | boxShadow: 11 | "0 8px 10px 1px rgba(" + 12 | hexToRgb(blackColor) + 13 | ", 0.14), 0 3px 14px 2px rgba(" + 14 | hexToRgb(blackColor) + 15 | ", 0.12), 0 5px 5px -3px rgba(" + 16 | hexToRgb(blackColor) + 17 | ", 0.2)", 18 | maxWidth: "200px", 19 | textAlign: "center", 20 | fontFamily: '"Helvetica Neue",Helvetica,Arial,sans-serif', 21 | fontSize: "12px", 22 | fontStyle: "normal", 23 | fontWeight: "400", 24 | textShadow: "none", 25 | textTransform: "none", 26 | letterSpacing: "normal", 27 | wordBreak: "normal", 28 | wordSpacing: "normal", 29 | wordWrap: "normal", 30 | whiteSpace: "normal", 31 | lineBreak: "auto" 32 | } 33 | }; 34 | export default tooltipStyle; 35 | -------------------------------------------------------------------------------- /src/component/table/Table.tsx: -------------------------------------------------------------------------------- 1 | import CustomTable from './TableGrid'; 2 | import {withSize} from "react-sizeme"; 3 | 4 | export default withSize()(CustomTable); 5 | -------------------------------------------------------------------------------- /src/component/table/style/tableStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | warningColor, 3 | primaryColor, 4 | dangerColor, 5 | successColor, 6 | infoColor, 7 | roseColor, 8 | grayColor, 9 | defaultFont, 10 | } from '../../style/material-dashboard-react'; 11 | import {createStyles, Theme} from "@material-ui/core"; 12 | 13 | const tableStyle = (theme: Theme) => createStyles({ 14 | warningTableHeader: { 15 | color: warningColor, 16 | }, 17 | primaryTableHeader: { 18 | color: primaryColor, 19 | }, 20 | dangerTableHeader: { 21 | color: dangerColor, 22 | }, 23 | successTableHeader: { 24 | color: successColor, 25 | }, 26 | infoTableHeader: { 27 | color: infoColor, 28 | }, 29 | roseTableHeader: { 30 | color: roseColor, 31 | }, 32 | grayTableHeader: { 33 | color: grayColor, 34 | }, 35 | table: { 36 | marginBottom: '0', 37 | marginTop: '0', 38 | width: '100%', 39 | maxWidth: '100%', 40 | backgroundColor: 'transparent', 41 | borderSpacing: '0', 42 | borderCollapse: 'collapse', 43 | }, 44 | tableHeadCell: { 45 | color: 'inherit', 46 | ...defaultFont, 47 | fontSize: '1em', 48 | }, 49 | tableCell: { 50 | ...defaultFont, 51 | lineHeight: '1.42857143', 52 | padding: '4px 2px', 53 | verticalAlign: 'middle', 54 | }, 55 | tableCellSmile: { 56 | textAlign: 'center', 57 | }, 58 | tableResponsive: { 59 | width: '100%', 60 | marginTop: theme.spacing(), 61 | overflowX: 'auto', 62 | }, 63 | tableCards1x: { 64 | overflowY: 'auto', 65 | // maxHeight: "220px", 66 | overflowScrolling: 'touch', 67 | position: 'relative', 68 | 69 | }, 70 | }); 71 | 72 | export default tableStyle; 73 | -------------------------------------------------------------------------------- /src/component/tasks/style/tasksStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | defaultFont, 3 | primaryColor, 4 | dangerColor, 5 | grayColor 6 | } from '../../style/material-dashboard-react' 7 | import tooltipStyle from '../../style/tooltipStyle' 8 | import checkboxAdnRadioStyle from "../../style/checkboxAdnRadioStyle"; 9 | import {createStyles, Theme} from "@material-ui/core"; 10 | 11 | const st: any = { 12 | ...tooltipStyle, 13 | ...checkboxAdnRadioStyle, 14 | table: { 15 | marginBottom: "0", 16 | overflow: "visible" 17 | }, 18 | tableRow: { 19 | position: "relative", 20 | borderBottom: "1px solid " + grayColor[5] 21 | }, 22 | tableActions: { 23 | display: "flex", 24 | border: "none", 25 | padding: "12px 8px !important", 26 | verticalAlign: "middle" 27 | }, 28 | tableCell: { 29 | ...defaultFont, 30 | padding: "8px", 31 | verticalAlign: "middle", 32 | border: "none", 33 | lineHeight: "1.42857143", 34 | fontSize: "14px" 35 | }, 36 | tableCellRTL: { 37 | textAlign: "right" 38 | }, 39 | tableActionButton: { 40 | width: "27px", 41 | height: "27px", 42 | padding: "0" 43 | }, 44 | tableActionButtonIcon: { 45 | width: "17px", 46 | height: "17px" 47 | }, 48 | edit: { 49 | backgroundColor: "transparent", 50 | color: primaryColor[0], 51 | boxShadow: "none" 52 | }, 53 | close: { 54 | backgroundColor: "transparent", 55 | color: dangerColor[0], 56 | boxShadow: "none" 57 | } 58 | }; 59 | 60 | const tasksStyle = (theme: Theme) => createStyles( st ); 61 | export default tasksStyle; 62 | -------------------------------------------------------------------------------- /src/component/windows/WindowContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | interface Props { 4 | 5 | } 6 | 7 | class WindowContainer extends React.Component { 8 | constructor(props: Props){ 9 | super(props); 10 | } 11 | 12 | render(){ 13 | return
14 | } 15 | } 16 | 17 | export default WindowContainer; 18 | -------------------------------------------------------------------------------- /src/containers/layouts/DashboardContainer.tsx: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | 3 | import { 4 | shiftNotification, addNotification, 5 | setUserSubscribedToPushNotification, setServiceWorkerSubscription, setPushNotificationSupported, 6 | serverStateFetch, webSocketOpen, webSocketClose 7 | } from '../../redux/actions'; 8 | 9 | import App from '../../layouts/dashboard/Dashboard'; 10 | import {RootState} from "../../redux/reducers"; 11 | 12 | const mapStateToProps = (state: RootState/*, ownProps*/) => ({ 13 | notifications: state.notifications, 14 | serverState: state.serverState 15 | }); 16 | 17 | const mapDispatchToProps = { 18 | addNotification, 19 | shiftNotification, 20 | setUserSubscribedToPushNotification, 21 | setServiceWorkerSubscription, 22 | setPushNotificationSupported, 23 | serverStateFetch, 24 | webSocketOpen, 25 | webSocketClose 26 | }; 27 | 28 | export default connect(mapStateToProps, mapDispatchToProps)(App); 29 | 30 | // export default withStyles(dashboardStyle)(App); 31 | -------------------------------------------------------------------------------- /src/containers/layouts/box/ConfigurationFormBoxContainer.ts: -------------------------------------------------------------------------------- 1 | import {connect} from "react-redux"; 2 | import {RootState} from "../../../redux/reducers"; 3 | import {configurationSelectors} from "../../../redux/reducers/configuration"; 4 | import { 5 | configurationFetch, 6 | configurationFieldUpdated, 7 | configurationAdd, 8 | addElementToHome, 9 | moduleInfoFetch, removeElementFromHome, resetDeviceFetch 10 | } from "../../../redux/actions"; 11 | import ConfigurationFormBox from "../../../layouts/box/ConfigurationFormBox"; 12 | import {homeSelectors} from "../../../redux/reducers/home"; 13 | import {ILayoutConfigured, ILayoutElement} from "../../../redux/types/home"; 14 | import {moduleInfoSelectors} from "../../../redux/reducers/moduleInfo"; 15 | 16 | const isElementInHome = (element: string, homeElements: ILayoutElement[]) => homeElements.some((elem: ILayoutElement) => elem.additionalInfo.boxType === element); 17 | 18 | const mapStateToProps = (state: RootState, ownProps: {boxType: string}) => ({ 19 | configuration: configurationSelectors.configuration(state), 20 | moduleInfo: moduleInfoSelectors.moduleInfo(state), 21 | isInHome: isElementInHome(ownProps.boxType, homeSelectors.elements(state)), 22 | isFetching: state.configuration.isFetching || state.resetDevice.isFetching, 23 | }); 24 | 25 | 26 | const mapDispatchToProps = { 27 | configurationFetch, 28 | configurationFieldUpdated, 29 | configurationAdd, 30 | addElementToHome, 31 | removeElementFromHome, 32 | resetDeviceFetch 33 | }; 34 | 35 | export default connect(mapStateToProps, mapDispatchToProps)(ConfigurationFormBox); 36 | -------------------------------------------------------------------------------- /src/containers/layouts/box/ModuleInfoBoxContainer.ts: -------------------------------------------------------------------------------- 1 | import {connect} from "react-redux"; 2 | import {RootState} from "../../../redux/reducers"; 3 | import {moduleInfoSelectors} from "../../../redux/reducers/moduleInfo"; 4 | import {moduleInfoFetch, addElementToHome, removeElementFromHome} from "../../../redux/actions"; 5 | import {homeSelectors} from "../../../redux/reducers/home"; 6 | import {ILayoutConfigured, ILayoutElement} from "../../../redux/types/home"; 7 | import ModuleInfoBox from "../../../layouts/box/ModuleInfoBox"; 8 | 9 | const isElementInHome = (element: string, homeElements: ILayoutElement[]) => homeElements.some((elem: ILayoutElement) => elem.additionalInfo.boxType === element); 10 | 11 | const mapStateToProps = (state: RootState, ownProps: {boxType: string}) => ({ 12 | moduleInfo: moduleInfoSelectors.moduleInfo(state), 13 | isInHome: isElementInHome(ownProps.boxType, homeSelectors.elements(state)), 14 | isFetching: state.moduleInfo.isFetching, 15 | }); 16 | 17 | 18 | const mapDispatchToProps = { 19 | moduleInfoFetch, 20 | addElementToHome, 21 | removeElementFromHome 22 | }; 23 | 24 | export default connect(mapStateToProps, mapDispatchToProps)(ModuleInfoBox); 25 | -------------------------------------------------------------------------------- /src/containers/layouts/box/ReceiveMessagesBoxContainer.ts: -------------------------------------------------------------------------------- 1 | import {connect} from "react-redux"; 2 | import {RootState} from "../../../redux/reducers"; 3 | import {configurationSelectors} from "../../../redux/reducers/configuration"; 4 | import { 5 | webSocketOpen, 6 | webSocketClose, 7 | addElementToHome, 8 | removeElementFromHome, 9 | webSocketSendMessage 10 | } from "../../../redux/actions"; 11 | import {homeSelectors} from "../../../redux/reducers/home"; 12 | import {ILayoutConfigured, ILayoutElement} from "../../../redux/types/home"; 13 | import {moduleInfoSelectors} from "../../../redux/reducers/moduleInfo"; 14 | import ReceiveMessagesBox from "../../../layouts/box/ReceiveMessagesBox"; 15 | import {webSocketSelectors} from "../../../redux/reducers/webSocket"; 16 | import {deviceMessagesSelectors} from "../../../redux/reducers/deviceMessages"; 17 | 18 | const isElementInHome = (element: string, homeElements: ILayoutElement[]) => homeElements.some((elem: ILayoutElement) => elem.additionalInfo.boxType === element); 19 | 20 | const mapStateToProps = (state: RootState, ownProps: {boxType: string}) => ({ 21 | isInHome: isElementInHome(ownProps.boxType, homeSelectors.elements(state)), 22 | isConnected: webSocketSelectors.isConnected(state), 23 | singleMessage: webSocketSelectors.singleMessage(state), 24 | receivingDeviceMessages: webSocketSelectors.receivingDeviceMessages(state), 25 | lastMessage: deviceMessagesSelectors.messageReceived(state), 26 | }); 27 | 28 | 29 | const mapDispatchToProps = { 30 | webSocketSendMessage, 31 | webSocketOpen, 32 | webSocketClose, 33 | addElementToHome, 34 | removeElementFromHome 35 | }; 36 | 37 | export default connect(mapStateToProps, mapDispatchToProps)(ReceiveMessagesBox); 38 | -------------------------------------------------------------------------------- /src/containers/layouts/box/SendTabBoxContainer.ts: -------------------------------------------------------------------------------- 1 | import {connect} from "react-redux"; 2 | import {RootState} from "../../../redux/reducers"; 3 | import {moduleInfoSelectors} from "../../../redux/reducers/moduleInfo"; 4 | import { moduleInfoFetch, 5 | addElementToHome, 6 | removeElementFromHome, 7 | configurationFetch, 8 | deviceMessagesSendTransparent, 9 | deviceMessagesSendBroadcast, 10 | deviceMessagesSendFixed, 11 | deviceMessagesFieldInvalid 12 | } from "../../../redux/actions"; 13 | import {homeSelectors} from "../../../redux/reducers/home"; 14 | import {ILayoutConfigured, ILayoutElement} from "../../../redux/types/home"; 15 | import ModuleInfoBox from "../../../layouts/box/ModuleInfoBox"; 16 | import {configurationSelectors} from "../../../redux/reducers/configuration"; 17 | import SendTabBox from "../../../layouts/box/SendTabBox"; 18 | import {FIDEX_TRANSMISSION} from "../../../redux/types/configuration"; 19 | 20 | const isElementInHome = (element: string, homeElements: ILayoutElement[]) => homeElements.some((elem: ILayoutElement) => elem.additionalInfo.boxType === element); 21 | 22 | const mapStateToProps = (state: RootState, ownProps: {boxType: string}) => ({ 23 | configuration: configurationSelectors.configuration(state), 24 | moduleInfo: moduleInfoSelectors.moduleInfo(state), 25 | isInHome: isElementInHome(ownProps.boxType, homeSelectors.elements(state)), 26 | isFetching: state.moduleInfo.isFetching || state.configuration.isFetching, 27 | tabToShow: ( 28 | configurationSelectors.configuration(state).OPTION.fixedTransmission=== 29 | FIDEX_TRANSMISSION.FT_TRANSPARENT_TRANSMISSION)?["transparent"]:["fixed", "broadcast"], 30 | }); 31 | 32 | 33 | const mapDispatchToProps = { 34 | configurationFetch, 35 | moduleInfoFetch, 36 | 37 | deviceMessagesSendTransparent, 38 | deviceMessagesSendBroadcast, 39 | deviceMessagesSendFixed, 40 | 41 | deviceMessagesFieldInvalid, 42 | 43 | addElementToHome, 44 | removeElementFromHome 45 | }; 46 | 47 | export default connect(mapStateToProps, mapDispatchToProps)(SendTabBox); 48 | -------------------------------------------------------------------------------- /src/containers/views/HomeContainer.jsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/containers/views/HomeContainer.jsx -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/favicon.ico -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | EByte Manager 20 | 21 |
22 | 23 | 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root'), 12 | ); 13 | 14 | // If you want your app to work offline and load faster, you can change 15 | // unregister() to register() below. Note this comes with some pitfalls. 16 | // Learn more about service workers: https://bit.ly/CRA-PWA 17 | serviceWorker.unregister(); 18 | -------------------------------------------------------------------------------- /src/layouts/GenericTypes.ts: -------------------------------------------------------------------------------- 1 | export type ThemeColors = 'warning' | 'success' | 'danger' | 'info' | 'primary' | 'rose'; 2 | -------------------------------------------------------------------------------- /src/layouts/Test.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/layouts/Test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import logo from '../logo.svg'; 3 | import './Test.css'; 4 | 5 | import { connect } from 'react-redux'; 6 | 7 | import { RootState } from '../redux/reducers'; 8 | import { versionSelectors } from '../redux/reducers/version'; 9 | 10 | import { setVersion, configurationFetch } from '../redux/actions'; 11 | 12 | import { FormattedMessage, injectIntl, WrappedComponentProps } from 'react-intl' 13 | 14 | // interface StateProps { 15 | // version: string, 16 | // date: string 17 | // } 18 | // 19 | // interface DispatchProps { 20 | // setVersion: VersionActions 21 | // } 22 | // 23 | interface OwnProps { 24 | backgroundColor: string; 25 | } 26 | // 27 | // type Props = StateProps & DispatchProps & OwnProps 28 | 29 | const mapState = (state: RootState) => ({ 30 | version: versionSelectors.appVersion(state), 31 | date: versionSelectors.appDate(state), 32 | }); 33 | 34 | const mapDispatch = { 35 | setVersion, 36 | configurationFetch 37 | }; 38 | 39 | type StateProps = ReturnType 40 | type DispatchProps = typeof mapDispatch 41 | 42 | type Props = StateProps & DispatchProps & OwnProps & 43 | // { placeholder: string, } & 44 | WrappedComponentProps 45 | 46 | class Test extends React.Component { 47 | constructor(props: Props) { 48 | super(props); 49 | 50 | props.configurationFetch(); 51 | 52 | this.state = { version: props.version }; 53 | } 54 | 55 | render() { 56 | return ( 57 |
58 |
59 | logo 60 |

61 | Edit 62 | {' '} 63 | src/App.tsx 64 | {' '} 65 | and save to reload. 66 | {' '} 67 | {this.props.version} 68 | {' '} 69 | {this.state.version} 70 |

71 | 77 | Learn React 78 | 79 |
this.props.setVersion('0.0.2', '123')}> Ciao
80 | 81 | {this.props.intl.formatMessage({ 82 | id: 'configuration.save.failed', // This ID could be anything else as well 83 | })} 84 | {/*
this.props.setVersion({version: '0.0.2', date: '123'})}> Ciao
*/} 85 | 86 |
87 |
88 | ); 89 | } 90 | } 91 | 92 | 93 | export default injectIntl( connect( 94 | mapState, 95 | mapDispatch, 96 | )(Test) ); 97 | // 98 | // export default Test; 99 | -------------------------------------------------------------------------------- /src/layouts/box/AboutBox.tsx: -------------------------------------------------------------------------------- 1 | import React, {FunctionComponent} from "react"; 2 | import GridContainer from "../../component/grid/GridContainer"; 3 | import GridItem from "../../component/grid/GridItem"; 4 | import Card from "../../component/card/Card"; 5 | import CardAvatar from "../../component/card/CardAvatar"; 6 | import CardBody from "../../component/card/CardBody"; 7 | import withStyles from "@material-ui/core/styles/withStyles"; 8 | import basicsStyle from "../../component/style/basicsStyle"; 9 | import avatar from '../../resources/images/bill.jpg'; 10 | import siteLogo from '../../resources/images/logo.jpg'; 11 | import {injectIntl} from "react-intl"; 12 | import Button from './../../component/customButtons/Button'; 13 | 14 | interface Props { 15 | classes: any, 16 | intl: any 17 | } 18 | 19 | const AboutBox: FunctionComponent = ({ classes }) => ( 20 |
21 | 22 | 23 | 24 | 25 | {/* e.preventDefault()}>*/} 26 | ... 27 | {/**/} 28 | 29 | 30 |
CREATOR
31 |

Renzo Mischianti

32 |

33 | renzo.mischianti@gmail.com 34 |

35 |

36 | 37 | A blog of digital electronics and programming (Bumblebee can't fly)
47 | https://www.mischianti.org 48 |
49 |

50 | 53 |
54 |
55 |
56 | 57 |
58 |
59 | ); 60 | 61 | // export default About; 62 | export default withStyles(basicsStyle)(injectIntl(AboutBox)); 63 | -------------------------------------------------------------------------------- /src/layouts/box/AboutLibraryBox.tsx: -------------------------------------------------------------------------------- 1 | import React, {FunctionComponent} from "react"; 2 | import GridContainer from "../../component/grid/GridContainer"; 3 | import GridItem from "../../component/grid/GridItem"; 4 | import Card from "../../component/card/Card"; 5 | import CardAvatar from "../../component/card/CardAvatar"; 6 | import CardBody from "../../component/card/CardBody"; 7 | import withStyles from "@material-ui/core/styles/withStyles"; 8 | import basicsStyle from "../../component/style/basicsStyle"; 9 | import avatar from '../../resources/images/favicon/android-icon-144x144.png'; 10 | import siteLogo from '../../resources/images/logo.jpg'; 11 | import {injectIntl} from "react-intl"; 12 | import Button from './../../component/customButtons/Button'; 13 | 14 | interface Props { 15 | classes: any, 16 | intl: any 17 | } 18 | 19 | const AboutLibraryBox: FunctionComponent = ({ classes }) => ( 20 |
21 | 22 | 23 | 24 | 25 | e.preventDefault()}> 26 | ... 27 | 28 | 29 | 30 |
Library
31 |

EByte Lora e32

32 |

MIT License

33 |

34 | renzo.mischianti@gmail.com 35 |

36 |

37 | 38 | A blog of digital electronics and programming (Bumblebee can't fly)
48 | https://www.mischianti.org/category/my-libraries/lora-e32-devices/ 49 |
50 |

51 | 54 |
55 |
56 |
57 | 58 |
59 |
60 | ); 61 | 62 | // export default About; 63 | export default withStyles(basicsStyle)(injectIntl(AboutLibraryBox)); 64 | -------------------------------------------------------------------------------- /src/layouts/box/Types.ts: -------------------------------------------------------------------------------- 1 | import {ThemeColors} from "../GenericTypes"; 2 | 3 | export interface IBox { 4 | addElementToHome: (elementType: string) => void, 5 | removeElementFromHome: (elementType: string) => void, 6 | boxType: string, 7 | isInHome: boolean, 8 | id: string, 9 | color: ThemeColors 10 | } 11 | -------------------------------------------------------------------------------- /src/layouts/box/boxes.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {ILayoutElement} from "../../redux/types/home"; 3 | 4 | import ConfigurationFormBoxContainer from "./../../containers/layouts/box/ConfigurationFormBoxContainer" 5 | import ModuleInfoBoxContainer from "./../../containers/layouts/box/ModuleInfoBoxContainer" 6 | import SendTabBoxContainer from "./../../containers/layouts/box/SendTabBoxContainer" 7 | import ReceiveMessagesBoxContainer from "./../../containers/layouts/box/ReceiveMessagesBoxContainer" 8 | 9 | interface IBoxes { 10 | [propName: string]: ILayoutElement; 11 | } 12 | 13 | const boxes: IBoxes = { 14 | receiveMessagesBoxContainer: { 15 | additionalInfo: { 16 | classObj: (id: string, props: any) => (), 17 | defaultProps: { 18 | color: 'primary', 19 | }, 20 | boxType: 'receiveMessagesBoxContainer', 21 | }, 22 | isBounded: undefined, 23 | isDraggable: undefined, 24 | isResizable: true, 25 | minW: 1, 26 | maxW: 5, 27 | minH: 2, 28 | maxH: 6, 29 | w: 2, 30 | h: 2, 31 | }, 32 | sendTabBoxContainer: { 33 | additionalInfo: { 34 | classObj: (id: string, props: any) => (), 35 | defaultProps: { 36 | color: 'danger', 37 | }, 38 | boxType: 'sendTabBoxContainer', 39 | }, 40 | isBounded: undefined, 41 | isDraggable: undefined, 42 | isResizable: true, 43 | minW: 1, 44 | maxW: 5, 45 | minH: 3, 46 | maxH: 6, 47 | w: 2, 48 | h: 3, 49 | }, 50 | moduleInfoBoxContainer: { 51 | additionalInfo: { 52 | classObj: (id: string, props: any) => (), 53 | defaultProps: { 54 | color: 'danger', 55 | }, 56 | boxType: 'moduleInfoBoxContainer', 57 | }, 58 | isBounded: false, 59 | isDraggable: true, 60 | isResizable: false, 61 | minW: 1, 62 | maxW: 1, 63 | minH: 2, 64 | maxH: 2, 65 | w: 1, 66 | h: 2, 67 | }, 68 | configurationFormBoxContainer: { 69 | additionalInfo: { 70 | classObj: (id: string, props: any) => (), 71 | defaultProps: { 72 | color: 'warning', 73 | }, 74 | boxType: 'configurationFormBoxContainer', 75 | }, 76 | isBounded: undefined, 77 | isDraggable: undefined, 78 | isResizable: true, 79 | minW: 1, 80 | maxW: 5, 81 | minH: 4, 82 | maxH: 8, 83 | w: 3, 84 | h: 4, 85 | }, 86 | 87 | }; 88 | 89 | export default boxes; 90 | -------------------------------------------------------------------------------- /src/layouts/box/utils/configuration.tsx: -------------------------------------------------------------------------------- 1 | import MenuItem from "@material-ui/core/MenuItem/MenuItem"; 2 | import React from "react"; 3 | 4 | export const getFrequences = (operatingFrequency: number): JSX.Element[] => { 5 | let freq: JSX.Element[] = []; 6 | for (var key=0; key<31; key++){ 7 | freq.push({(key+operatingFrequency)+"MHz"}); 8 | } 9 | // return (Array.from({length: 31}) .forEach((key) => { 10 | // freq.push({(key+operatingFrequency)+"MHz"}); 11 | // })) 12 | return freq; 13 | } 14 | export const getADD = (): JSX.Element[] => { 15 | let freq: JSX.Element[] = []; 16 | for (var key=0; key<255; key++){ 17 | freq.push({key}); 18 | } 19 | // return (Array.from({length: 31}) .forEach((key) => { 20 | // freq.push({(key+operatingFrequency)+"MHz"}); 21 | // })) 22 | return freq; 23 | } 24 | -------------------------------------------------------------------------------- /src/layouts/dashboard/style/dashboardStyle.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | drawerWidth, 3 | transition, 4 | container 5 | } from "../../../component/style/material-dashboard-react"; 6 | import { createStyles, Theme } from '@material-ui/core/styles'; 7 | 8 | const appStyle = (theme: Theme) => createStyles({ 9 | wrapper: { 10 | position: "relative", 11 | top: "0", 12 | height: "100vh" 13 | }, 14 | mainPanel: { 15 | [theme.breakpoints.up("md")]: { 16 | width: `calc(100% - ${drawerWidth}px)` 17 | }, 18 | overflow: "auto", 19 | position: "relative", 20 | float: "right", 21 | ...transition, 22 | maxHeight: "100%", 23 | width: "100%", 24 | overflowScrolling: "touch" 25 | }, 26 | content: { 27 | marginTop: "70px", 28 | padding: "30px 15px", 29 | minHeight: "calc(100vh - 170px)" 30 | }, 31 | container, 32 | map: { 33 | marginTop: "70px" 34 | } 35 | }); 36 | 37 | export default appStyle; 38 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "EByteManager", 3 | "short_name": "EByteManager", 4 | "start_url": "./", 5 | "display": "standalone", 6 | "theme_color": "#ffff00", 7 | "background_color": "#ffff00", 8 | "description": "EByte Manager WebApp.", 9 | "orientation": "portrait", 10 | 11 | "gcm_sender_id": "123456788", 12 | "gcm_user_visible_only": true, 13 | "permissions": [ 14 | "gcm" 15 | ], 16 | "icons": [ 17 | { 18 | "src": "resources/images/favicon/android-icon-36x36.png", 19 | "sizes": "36x36", 20 | "type": "image\/png", 21 | "density": "0.75" 22 | }, 23 | { 24 | "src": "resources/images/favicon/android-icon-48x48.png", 25 | "sizes": "48x48", 26 | "type": "image\/png", 27 | "density": "1.0" 28 | }, 29 | { 30 | "src": "resources/images/favicon/android-icon-72x72.png", 31 | "sizes": "72x72", 32 | "type": "image\/png", 33 | "density": "1.5" 34 | }, 35 | { 36 | "src": "resources/images/favicon/android-icon-96x96.png", 37 | "sizes": "96x96", 38 | "type": "image\/png", 39 | "density": "2.0" 40 | }, 41 | { 42 | "src": "resources/images/favicon/android-icon-144x144.png", 43 | "sizes": "144x144", 44 | "type": "image\/png", 45 | "density": "3.0" 46 | }, 47 | { 48 | "src": "resources/images/favicon/android-icon-192x192.png", 49 | "sizes": "192x192", 50 | "type": "image\/png", 51 | "density": "4.0" 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/redux/actions/configuration.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CONFIGURATION_FETCH, 3 | CONFIGURATION_FETCH_CANCEL, 4 | CONFIGURATION_FETCH_FULFILLED, 5 | CONFIGURATION_FETCH_REJECTED, 6 | CONFIGURATION_FIELD_UPDATED, 7 | CONFIGURATION_FIELD_INVALID, 8 | CONFIGURATION_ADD, 9 | CONFIGURATION_ADD_SUCCESS, 10 | CONFIGURATION_ADD_FAILED, IConfiguration, ConfigurationActions 11 | } from "../types/configuration"; 12 | 13 | 14 | // action creators 15 | export const configurationFetch = (): ConfigurationActions => ({ 16 | type: CONFIGURATION_FETCH, 17 | isFetching: false, 18 | fetchStatus: `start fetching... ${(new Date()).toLocaleString()}` 19 | }); 20 | export const configurationFetchCancel = (): ConfigurationActions => ( 21 | { 22 | type: CONFIGURATION_FETCH_CANCEL, 23 | isFetching: false, 24 | fetchStatus: 'user cancelled' 25 | 26 | } 27 | ); 28 | export const configurationFetchFulfilled = (configuration: IConfiguration, lastUpdate: Date): ConfigurationActions => ({ 29 | type: CONFIGURATION_FETCH_FULFILLED, 30 | configuration: configuration, 31 | lastUpdate: lastUpdate, 32 | isFetching: false, 33 | fetchStatus: `Results from ${(new Date()).toLocaleString()}` 34 | }); 35 | 36 | export const configurationFetchRejected = (err: any): ConfigurationActions => { 37 | return { 38 | type: CONFIGURATION_FETCH_REJECTED, 39 | err: err, 40 | isFetching: false, 41 | fetchStatus: `errored: ${err.message}` 42 | } 43 | }; 44 | 45 | // action creators 46 | export const configurationFieldUpdated = (configuration: IConfiguration, lastUpdate: Date): ConfigurationActions => ({ 47 | type: CONFIGURATION_FIELD_UPDATED, 48 | configuration: configuration, 49 | lastUpdate: lastUpdate, 50 | isFetching: false 51 | }); 52 | 53 | export const configurationFieldInvalid = (errors: string[], configuration: IConfiguration): ConfigurationActions => ({ 54 | type: CONFIGURATION_FIELD_INVALID, 55 | errors, 56 | configuration, 57 | isFetching: false, 58 | fetchStatus: 'field invalid' 59 | 60 | }); 61 | 62 | export const configurationAdd = (configuration: IConfiguration, lastUpdate: Date): ConfigurationActions => ({ 63 | type: CONFIGURATION_ADD, 64 | configuration: configuration, 65 | lastUpdate: lastUpdate, 66 | isFetching: true 67 | }); 68 | export const configurationAddSuccess = (configuration: IConfiguration): ConfigurationActions => ({ 69 | type: CONFIGURATION_ADD_SUCCESS, 70 | isFetching: false, 71 | configuration: configuration 72 | }); 73 | 74 | export const configurationAddFailed = (err: Error): ConfigurationActions => ({ 75 | type: CONFIGURATION_ADD_FAILED, 76 | err: err, 77 | isFetching: false, 78 | fetchStatus: `errored: ${err.message}` 79 | }); 80 | 81 | export const actions = { 82 | configurationFieldUpdated, 83 | configurationFieldInvalid, 84 | // configurationAdd, 85 | configurationAddSuccess, 86 | configurationAddFailed, 87 | 88 | configurationFetch, 89 | configurationFetchCancel, 90 | configurationFetchFulfilled, 91 | configurationFetchRejected 92 | }; 93 | -------------------------------------------------------------------------------- /src/redux/actions/configurationPage.ts: -------------------------------------------------------------------------------- 1 | 2 | // unique key namespace used by combineReducers. 3 | // By convention it will match the directory structure to 4 | // make it easy to locate the src. 5 | // Also action types will prefix with the capitalized version 6 | import {ILayoutConfigured} from "../types/home"; 7 | import {CONFIGURATION_PAGE_SET_LAYOUTS, ConfigurationPageActions} from "../types/configurationPage"; 8 | 9 | 10 | // action creators 11 | export const setConfigurationPageLayout = (layouts: ILayoutConfigured): ConfigurationPageActions => ({ 12 | type: CONFIGURATION_PAGE_SET_LAYOUTS, 13 | layouts 14 | }); 15 | 16 | export const actions = { 17 | setConfigurationPageLayout 18 | }; 19 | -------------------------------------------------------------------------------- /src/redux/actions/home.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | // action creators 4 | import { 5 | HOME_SET_LAYOUTS, 6 | HOME_ADD_ELEMENT, 7 | HOME_REMOVE_ELEMENT, 8 | // ILayout, 9 | HomeActions, 10 | ILayoutElement, ILayoutConfigured 11 | } from "../types/home"; 12 | 13 | export const setHomeLayout = (layouts: ILayoutConfigured): HomeActions => ({ 14 | type: HOME_SET_LAYOUTS, 15 | layouts 16 | }); 17 | 18 | export const addElementToHome = (element: any): HomeActions => ({ 19 | type: HOME_ADD_ELEMENT, 20 | element 21 | }); 22 | 23 | export const removeElementFromHome = (element: string): HomeActions => ({ 24 | type: HOME_REMOVE_ELEMENT, 25 | element: element 26 | }); 27 | 28 | export const actions = { 29 | setHomeLayout, 30 | addElementToHome, 31 | removeElementFromHome 32 | }; 33 | -------------------------------------------------------------------------------- /src/redux/actions/moduleInfo.ts: -------------------------------------------------------------------------------- 1 | import { 2 | MODULE_INFO_FETCH, 3 | MODULE_INFO_FETCH_CANCEL, 4 | MODULE_INFO_FETCH_FULFILLED, 5 | MODULE_INFO_FETCH_REJECTED, 6 | IModuleInfo, ModuleInfoActions 7 | } from "../types/moduleInfo"; 8 | 9 | 10 | // action creators 11 | export const moduleInfoFetch = (): ModuleInfoActions => ({ 12 | type: MODULE_INFO_FETCH, 13 | isFetching: false, 14 | fetchStatus: `start fetching... ${(new Date()).toLocaleString()}` 15 | }); 16 | export const moduleInfoFetchCancel = (): ModuleInfoActions => ( 17 | { 18 | type: MODULE_INFO_FETCH_CANCEL, 19 | isFetching: false, 20 | fetchStatus: 'user cancelled' 21 | 22 | } 23 | ); 24 | export const moduleInfoFetchFulfilled = (moduleInfo: IModuleInfo, lastUpdate: Date): ModuleInfoActions => ({ 25 | type: MODULE_INFO_FETCH_FULFILLED, 26 | moduleInfo: moduleInfo, 27 | lastUpdate: lastUpdate, 28 | isFetching: false, 29 | fetchStatus: `Results from ${(new Date()).toLocaleString()}` 30 | }); 31 | 32 | export const moduleInfoFetchRejected = (err: any): ModuleInfoActions => { 33 | return { 34 | type: MODULE_INFO_FETCH_REJECTED, 35 | err: err, 36 | isFetching: false, 37 | fetchStatus: `errored: ${err.message}` 38 | } 39 | }; 40 | 41 | export const actions = { 42 | moduleInfoFetch, 43 | moduleInfoFetchCancel, 44 | moduleInfoFetchFulfilled, 45 | moduleInfoFetchRejected 46 | }; 47 | -------------------------------------------------------------------------------- /src/redux/actions/notifications.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ADD_NOTIFICATION, 3 | GET_CURRENT_NOTIFICATION, 4 | SHIFT_NOTIFICATION, 5 | INotification, 6 | NotificationsActions 7 | } from "../types/notifications"; 8 | 9 | 10 | export const addNotification = (notification: INotification): NotificationsActions => ({ 11 | type: ADD_NOTIFICATION, 12 | notification 13 | }); 14 | 15 | export const shiftNotification = (): NotificationsActions => ({ 16 | type: SHIFT_NOTIFICATION 17 | }); 18 | 19 | export const getCurrentNotification = (): NotificationsActions => ({ 20 | type: GET_CURRENT_NOTIFICATION 21 | }); 22 | 23 | export const actions = { 24 | addNotification, 25 | shiftNotification, 26 | getCurrentNotification 27 | } 28 | -------------------------------------------------------------------------------- /src/redux/actions/resetDevice.ts: -------------------------------------------------------------------------------- 1 | import { 2 | RESET_DEVICE_FETCH, 3 | RESET_DEVICE_FETCH_CANCEL, 4 | RESET_DEVICE_FETCH_FULFILLED, 5 | RESET_DEVICE_FETCH_REJECTED, 6 | IStatus, ResetDeviceActions 7 | } from "../types/resetDevice"; 8 | 9 | 10 | // action creators 11 | export const resetDeviceFetch = (): ResetDeviceActions => ({ 12 | type: RESET_DEVICE_FETCH, 13 | isFetching: false, 14 | fetchStatus: `start fetching... ${(new Date()).toLocaleString()}` 15 | }); 16 | export const resetDeviceFetchCancel = (): ResetDeviceActions => ( 17 | { 18 | type: RESET_DEVICE_FETCH_CANCEL, 19 | isFetching: false, 20 | fetchStatus: 'user cancelled' 21 | 22 | } 23 | ); 24 | export const resetDeviceFetchFulfilled = (status: IStatus, lastUpdate: Date): ResetDeviceActions => ({ 25 | type: RESET_DEVICE_FETCH_FULFILLED, 26 | status: status, 27 | lastUpdate: lastUpdate, 28 | isFetching: false, 29 | fetchStatus: `Results from ${(new Date()).toLocaleString()}` 30 | }); 31 | 32 | export const resetDeviceFetchRejected = (err: any): ResetDeviceActions => { 33 | return { 34 | type: RESET_DEVICE_FETCH_REJECTED, 35 | err: err, 36 | isFetching: false, 37 | fetchStatus: `errored: ${err.message}` 38 | } 39 | }; 40 | 41 | export const actions = { 42 | resetDeviceFetch, 43 | resetDeviceFetchCancel, 44 | resetDeviceFetchFulfilled, 45 | resetDeviceFetchRejected 46 | }; 47 | -------------------------------------------------------------------------------- /src/redux/actions/sendReceiveDataPage.ts: -------------------------------------------------------------------------------- 1 | 2 | // unique key namespace used by combineReducers. 3 | // By convention it will match the directory structure to 4 | // make it easy to locate the src. 5 | // Also action types will prefix with the capitalized version 6 | import {ILayoutConfigured} from "../types/home"; 7 | import {SEND_RECEIVE_DATA_PAGE_SET_LAYOUTS, SendReceiveDataPageActions} from "../types/sendReceiveDataPage"; 8 | 9 | 10 | // action creators 11 | export const setSendReceiveDataPageLayout = (layouts: ILayoutConfigured): SendReceiveDataPageActions => ({ 12 | type: SEND_RECEIVE_DATA_PAGE_SET_LAYOUTS, 13 | layouts 14 | }); 15 | 16 | export const actions = { 17 | setSendReceiveDataPageLayout 18 | }; 19 | -------------------------------------------------------------------------------- /src/redux/actions/serverState.ts: -------------------------------------------------------------------------------- 1 | // action creators 2 | import { 3 | SERVER_STATE_FETCH, SERVER_STATE_BATTERY_FETCH_FULFILLED, SERVER_STATE_FETCH_CANCEL, 4 | SERVER_STATE_FETCH_FULFILLED, SERVER_STATE_FETCH_REJECTED, 5 | SERVER_STATE_WIFI_STRENGHT_FETCH_FULFILLED, ServerStateActions 6 | } from "../types/serverState"; 7 | 8 | export const serverStateFetch = () => ({ 9 | type: SERVER_STATE_FETCH 10 | }); 11 | export const serverStateFetchCancel = () => ( 12 | { 13 | type: SERVER_STATE_FETCH_CANCEL 14 | } 15 | ); 16 | export const serverStateFetchFulfilled = (data: any, lastUpdate: Date): ServerStateActions => ({ 17 | type: SERVER_STATE_FETCH_FULFILLED, 18 | data: data, 19 | lastUpdate: lastUpdate, 20 | isFetching: false, 21 | fetchStatus: `Results from ${(new Date()).toLocaleString()}` 22 | }); 23 | 24 | export const serverStateBatteryFetchFulfilled = (data: any): ServerStateActions => ({ 25 | type: SERVER_STATE_BATTERY_FETCH_FULFILLED, 26 | voltage: data.voltage, 27 | lastUpdate: data.lastUpdate 28 | }); 29 | 30 | export const serverStateWIFIStrenghtFetchFulfilled = (data: any): ServerStateActions => ({ 31 | type: SERVER_STATE_WIFI_STRENGHT_FETCH_FULFILLED, 32 | signalStrengh: data.signalStrengh, 33 | lastUpdate: data.lastUpdate 34 | }); 35 | 36 | export const serverStateFetchRejected = (err: any): ServerStateActions => ({ 37 | type: SERVER_STATE_FETCH_REJECTED, 38 | err, 39 | error: true, 40 | isFetching: false, 41 | fetchStatus: `errored: ${err.message}` 42 | }); 43 | 44 | export const actions = { 45 | serverStateFetch, 46 | serverStateFetchCancel, 47 | serverStateFetchFulfilled, 48 | serverStateFetchRejected, 49 | serverStateBatteryFetchFulfilled, 50 | serverStateWIFIStrenghtFetchFulfilled 51 | }; 52 | -------------------------------------------------------------------------------- /src/redux/actions/subscriptionsServiceWorker.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SET_SUBSCRIPTION_SERVICE_WORKER, 3 | SET_PUSH_NOTIFICATION_IS_SUPPORTED, 4 | SET_USER_SUBSCRIBED_TO_PUSH_NOTIFICATION, SubscriptionsServiceWorkerActions 5 | } from "../types/subscriptionsServiceWorker"; 6 | 7 | 8 | export const setServiceWorkerSubscription = (isServiceWorkerSubscribed: boolean, registration: any): SubscriptionsServiceWorkerActions => ({ 9 | type: SET_SUBSCRIPTION_SERVICE_WORKER, 10 | isServiceWorkerSubscribed: isServiceWorkerSubscribed, 11 | registration: registration 12 | }); 13 | 14 | export const setPushNotificationSupported = (isPushNotificationSupported: boolean): SubscriptionsServiceWorkerActions => ({ 15 | type: SET_PUSH_NOTIFICATION_IS_SUPPORTED, 16 | isPushNotificationSupported: isPushNotificationSupported 17 | }); 18 | 19 | export const setUserSubscribedToPushNotification = (isUserSubscribedToPushNotification: boolean): SubscriptionsServiceWorkerActions => ({ 20 | type: SET_USER_SUBSCRIBED_TO_PUSH_NOTIFICATION, 21 | isUserSubscribedToPushNotification: isUserSubscribedToPushNotification 22 | }); 23 | 24 | export const actions = { 25 | setServiceWorkerSubscription, 26 | setPushNotificationSupported, 27 | setUserSubscribedToPushNotification 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/redux/actions/version.ts: -------------------------------------------------------------------------------- 1 | import { 2 | // IVersion, 3 | SET_VERSION, VersionActions, 4 | } from '../types/version'; 5 | 6 | export const setVersion = (version: string, date: string): VersionActions => ({ 7 | type: SET_VERSION, 8 | payload: { version, date }, 9 | }); 10 | -------------------------------------------------------------------------------- /src/redux/actions/webSocket.ts: -------------------------------------------------------------------------------- 1 | 2 | // action creators 3 | import { 4 | WEB_SOCKET_CLOSE, 5 | WEB_SOCKET_CONNECT, 6 | WEB_SOCKET_DISCONNECT, 7 | WEB_SOCKET_ERROR, 8 | WEB_SOCKET_MESSAGE, 9 | WEB_SOCKET_OPEN, 10 | WEB_SOCKET_RECEIVING_DEVICE_MESSAGE, 11 | WEB_SOCKET_SEND_MESSAGE, 12 | WEB_SOCKET_SINGLE_MESSAGE, 13 | WebSocketActions 14 | } from "../types/webSocket"; 15 | 16 | export const webSocketOpen = (): WebSocketActions => ({ 17 | type: WEB_SOCKET_OPEN, 18 | isConnected: false, 19 | lastUpdate: new Date() 20 | }); 21 | export const webSocketSingleMessage = (singleMessage: boolean): WebSocketActions => ({ 22 | type: WEB_SOCKET_SINGLE_MESSAGE, 23 | singleMessage 24 | }); 25 | export const webSocketReceivingDeviceMessages = (receivingDeviceMessages: boolean): WebSocketActions => ({ 26 | type: WEB_SOCKET_RECEIVING_DEVICE_MESSAGE, 27 | receivingDeviceMessages 28 | }); 29 | // action creators 30 | export const webSocketConnect = (): WebSocketActions => ({ 31 | type: WEB_SOCKET_CONNECT, 32 | isConnected: true, 33 | lastUpdate: new Date() 34 | }); 35 | // action creators 36 | export const webSocketDisconnect = (): WebSocketActions => ({ 37 | type: WEB_SOCKET_DISCONNECT, 38 | isConnected: false, 39 | lastUpdate: new Date() 40 | }); 41 | export const webSocketClose = (): WebSocketActions => ({ 42 | type: WEB_SOCKET_CLOSE, 43 | // isConnected: false, 44 | lastUpdate: new Date() 45 | }); 46 | export const webSocketError = (event: Event): WebSocketActions => ({ 47 | type: WEB_SOCKET_ERROR, 48 | error: event, 49 | isConnected: false, 50 | lastUpdate: new Date() 51 | }); 52 | export const webSocketMessage = (message: any): WebSocketActions => ({ 53 | type: WEB_SOCKET_MESSAGE, 54 | message: message 55 | }); 56 | export const webSocketSendMessage = (message: any): WebSocketActions => ({ 57 | type: WEB_SOCKET_SEND_MESSAGE, 58 | message 59 | }); 60 | 61 | export const actions = { 62 | webSocketOpen, 63 | webSocketConnect, 64 | webSocketDisconnect, 65 | webSocketClose, 66 | webSocketError, 67 | webSocketMessage, 68 | webSocketSendMessage, 69 | webSocketSingleMessage, 70 | webSocketReceivingDeviceMessages 71 | }; 72 | -------------------------------------------------------------------------------- /src/redux/config.js: -------------------------------------------------------------------------------- 1 | export const MICROCONTROLLER_ADRESS = `${(window.settings.localIP) ? window.settings.localIP : window.location.hostname}:${window.settings.localRestPort}`; 2 | export const MICROCONTROLLER_WS_ADRESS = `ws://${(window.settings.localIP) ? window.settings.localIP : window.location.hostname}:${window.settings.localWSPort}`; 3 | 4 | export const CONFIGURATION_ENDPOINT = "configuration"; 5 | export const MODULE_INFO_ENDPOINT = "moduleInfo"; 6 | export const SERVER_STATE_ENDPOINT = "serverState"; 7 | 8 | export const TRANSPARENT_TRANSMISSION_ENDPOINT = "transparentMessage"; 9 | export const FIXED_TRANSMISSION_ENDPOINT = "fixedMessage"; 10 | export const BROADCAST_TRANSMISSION_ENDPOINT = "broadcastMessage"; 11 | export const RESET_DEVICE_ENDPOINT = "resetModule"; 12 | -------------------------------------------------------------------------------- /src/redux/logic/configurationGET.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { createLogic } from 'redux-logic'; 3 | // import moment from 'moment'; 4 | 5 | 6 | import { MICROCONTROLLER_ADRESS, CONFIGURATION_ENDPOINT } from '../config'; 7 | 8 | 9 | import { 10 | CONFIGURATION_FETCH, CONFIGURATION_FETCH_CANCEL, 11 | CONFIGURATION_FETCH_REJECTED, IConfiguration //, CONFIGURATION_FETCH_FULFILLED 12 | } from "../types/configuration"; 13 | import {addNotification, configurationFetchFulfilled, configurationFetchRejected} from "../actions"; 14 | import {FormattedMessage} from "react-intl"; 15 | 16 | // const delay = 10; // 4s delay for interactive use of cancel/take latest 17 | 18 | const configurationFetchLogic = createLogic({ 19 | type: CONFIGURATION_FETCH, 20 | cancelType: CONFIGURATION_FETCH_CANCEL, 21 | latest: true, // take latest only 22 | debounce: 1000, 23 | 24 | processOptions: { 25 | dispatchReturn: true, 26 | // successType: CONFIGURATION_FETCH_FULFILLED, //configurationFetchFulfilled, // CONFIGURATION_FETCH_FULFILLED, // 27 | // failType: CONFIGURATION_FETCH_REJECTED, //configurationFetchRejected // CONFIGURATION_FETCH_REJECTED //configurationFetchRejecte 28 | }, 29 | 30 | process({ httpClient, getState, action }, dispatch, done) { 31 | return httpClient.get(`http://${MICROCONTROLLER_ADRESS}/${CONFIGURATION_ENDPOINT}`) 32 | .then((resp: any) => { 33 | // const lastUpdate = new Date(moment(resp.data.lastUpdate, 'DD/MM/YYYY HH:mm:ss').valueOf()); 34 | const data = resp.data; 35 | 36 | const conf:IConfiguration = data.configuration; 37 | return { configuration: conf, lastUpdate: new Date() }; 38 | }) 39 | .then((payload: any) =>{ 40 | if (payload.configuration && payload.configuration.CHAN>=0 && payload.configuration.CHAN<41){ 41 | dispatch(configurationFetchFulfilled(payload.configuration, payload.lastUpdate)); 42 | }else{ 43 | dispatch(addNotification({ message: , variant: 'warning', autoHide: 0 })); 44 | } 45 | } 46 | ).catch(reason => { 47 | dispatch(configurationFetchRejected(reason)) 48 | }) 49 | .then(() => done()); 50 | } 51 | }); 52 | 53 | export default [ 54 | configurationFetchLogic 55 | ]; 56 | -------------------------------------------------------------------------------- /src/redux/logic/index.ts: -------------------------------------------------------------------------------- 1 | import configurationGET from './configurationGET'; 2 | import moduleInfoGET from './moduleInfoGET'; 3 | 4 | import configurationPOST from './configurationPOST'; 5 | 6 | import webSocket from './webSocket'; 7 | import messageTransparentPOST from "./messageTransparentPOST"; 8 | import messageBroadcastPOST from "./messageBroadcastPOST"; 9 | import messageFixedPOST from "./messageFixedPOST"; 10 | import resetDeviceGET from "./resetDeviceGET"; 11 | 12 | export default [ 13 | ...configurationGET, 14 | ...moduleInfoGET, 15 | ...configurationPOST, 16 | ...messageTransparentPOST, 17 | ...messageBroadcastPOST, 18 | ...messageFixedPOST, 19 | ...webSocket, 20 | ...resetDeviceGET 21 | ]; 22 | -------------------------------------------------------------------------------- /src/redux/logic/moduleInfoGET.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { createLogic } from 'redux-logic'; 3 | // import moment from 'moment'; 4 | 5 | 6 | import { MICROCONTROLLER_ADRESS, MODULE_INFO_ENDPOINT } from '../config'; 7 | 8 | 9 | import { 10 | MODULE_INFO_FETCH, MODULE_INFO_FETCH_CANCEL, 11 | MODULE_INFO_FETCH_REJECTED, IModuleInfo, frequencyFromModuleInfo //, MODULE_INFO_FETCH_FULFILLED 12 | } from "../types/moduleInfo"; 13 | import {addNotification, moduleInfoFetchFulfilled, moduleInfoFetchRejected} from "../actions"; 14 | import {FormattedMessage} from "react-intl"; 15 | 16 | // const delay = 10; // 4s delay for interactive use of cancel/take latest 17 | 18 | const moduleInfoFetchLogic = createLogic({ 19 | type: MODULE_INFO_FETCH, 20 | cancelType: MODULE_INFO_FETCH_CANCEL, 21 | latest: true, // take latest only 22 | debounce: 1000, 23 | 24 | processOptions: { 25 | dispatchReturn: true, 26 | // successType: MODULE_INFO_FETCH_FULFILLED, //moduleInfoFetchFulfilled, // MODULE_INFO_FETCH_FULFILLED, // 27 | // failType: MODULE_INFO_FETCH_REJECTED, //moduleInfoFetchRejected // MODULE_INFO_FETCH_REJECTED //moduleInfoFetchRejecte 28 | }, 29 | 30 | process({ httpClient, getState, action }, dispatch, done) { 31 | return httpClient.get(`http://${MICROCONTROLLER_ADRESS}/${MODULE_INFO_ENDPOINT}`) 32 | .then((resp: any) => { 33 | // const lastUpdate = new Date(moment(resp.data.lastUpdate, 'DD/MM/YYYY HH:mm:ss').valueOf()); 34 | const data = resp.data; 35 | 36 | const conf:IModuleInfo = data.moduleInfo; 37 | return { moduleInfo: conf, lastUpdate: new Date() }; 38 | }) 39 | .then((payload: any) =>{ 40 | if (Object.keys(frequencyFromModuleInfo).indexOf(payload.moduleInfo.frequency)>-1){ 41 | // if (payload.moduleInfo.frequency){ 42 | dispatch(moduleInfoFetchFulfilled(payload.moduleInfo, payload.lastUpdate)); 43 | }else{ 44 | dispatch(addNotification({ message: , variant: 'warning', autoHide: 0 })); 45 | } 46 | } 47 | ).catch(reason => { 48 | dispatch(moduleInfoFetchRejected(reason)) 49 | }) 50 | .then(() => done()); 51 | } 52 | }); 53 | 54 | export default [ 55 | moduleInfoFetchLogic 56 | ]; 57 | -------------------------------------------------------------------------------- /src/redux/logic/resetDeviceGET.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { createLogic } from 'redux-logic'; 3 | // import moment from 'moment'; 4 | 5 | 6 | import { MICROCONTROLLER_ADRESS, RESET_DEVICE_ENDPOINT } from '../config'; 7 | 8 | 9 | import { 10 | RESET_DEVICE_FETCH, RESET_DEVICE_FETCH_CANCEL, 11 | RESET_DEVICE_FETCH_REJECTED, IStatus//, RESET_DEVICE_FETCH_FULFILLED 12 | } from "../types/resetDevice"; 13 | import {addNotification, resetDeviceFetchFulfilled, resetDeviceFetchRejected} from "../actions"; 14 | import {FormattedMessage} from "react-intl"; 15 | 16 | // const delay = 10; // 4s delay for interactive use of cancel/take latest 17 | 18 | const resetDeviceFetchLogic = createLogic({ 19 | type: RESET_DEVICE_FETCH, 20 | cancelType: RESET_DEVICE_FETCH_CANCEL, 21 | latest: true, // take latest only 22 | debounce: 1000, 23 | 24 | processOptions: { 25 | dispatchReturn: true, 26 | // successType: RESET_DEVICE_FETCH_FULFILLED, //resetDeviceFetchFulfilled, // RESET_DEVICE_FETCH_FULFILLED, // 27 | // failType: RESET_DEVICE_FETCH_REJECTED, //resetDeviceFetchRejected // RESET_DEVICE_FETCH_REJECTED //resetDeviceFetchRejecte 28 | }, 29 | 30 | process({ httpClient, getState, action }, dispatch, done) { 31 | return httpClient.get(`http://${MICROCONTROLLER_ADRESS}/${RESET_DEVICE_ENDPOINT}`) 32 | .then((resp: any) => { 33 | // const lastUpdate = new Date(moment(resp.data.lastUpdate, 'DD/MM/YYYY HH:mm:ss').valueOf()); 34 | const data = resp.data; 35 | 36 | const conf:IStatus = data.status; 37 | return { status: conf, lastUpdate: new Date() }; 38 | }) 39 | .then((payload: any) =>{ 40 | if (!payload.status.error) { 41 | dispatch(addNotification({ 42 | message: , 43 | variant: 'success', 44 | autoHide: 0 45 | })); 46 | dispatch(resetDeviceFetchFulfilled(payload.status, payload.lastUpdate)); 47 | }else{ 48 | dispatch(resetDeviceFetchRejected({message: 'Reset: ' + payload.status.description})) 49 | 50 | } 51 | } 52 | ).catch(reason => { 53 | dispatch(resetDeviceFetchRejected(reason)) 54 | }) 55 | .then(() => done()); 56 | } 57 | }); 58 | 59 | export default [ 60 | resetDeviceFetchLogic 61 | ]; 62 | -------------------------------------------------------------------------------- /src/redux/logic/serverState.ts: -------------------------------------------------------------------------------- 1 | import { createLogic } from 'redux-logic'; 2 | import axios from 'axios'; 3 | 4 | import { MICROCONTROLLER_ADRESS, SERVER_STATE_ENDPOINT } from '../config'; 5 | 6 | import { 7 | SERVER_STATE_FETCH, SERVER_STATE_FETCH_CANCEL, SERVER_STATE_FETCH_REJECTED, SERVER_STATE_FETCH_FULFILLED 8 | } from "../types/serverState"; 9 | import { serverStateFetchFulfilled, 10 | serverStateFetchRejected } from "../actions"; 11 | 12 | const delay = 10; // 4s delay for interactive use of cancel/take latest 13 | 14 | const serverStateFetchLogic = createLogic({ 15 | type: SERVER_STATE_FETCH, 16 | cancelType: SERVER_STATE_FETCH_CANCEL, 17 | latest: true, // take latest only 18 | 19 | processOptions: { 20 | dispatchReturn: true, 21 | successType: SERVER_STATE_FETCH_FULFILLED, //serverStateFetchFulfilled, // SERVER_STATE_FETCH_FULFILLED, // 22 | failType: serverStateFetchRejected // SERVER_STATE_FETCH_REJECTED //serverStateFetchRejecte 23 | }, 24 | 25 | process({ httpClient, getState, action }, dispatch, done) { 26 | return httpClient.get(`http://${MICROCONTROLLER_ADRESS}/${SERVER_STATE_ENDPOINT}`) 27 | .then((resp) => { 28 | const lastUpdate = new Date(resp.data.lastUpdate); 29 | const data = resp.data; 30 | 31 | return { data, lastUpdate }; 32 | }); 33 | } 34 | }); 35 | 36 | export default [ 37 | serverStateFetchLogic 38 | ]; 39 | -------------------------------------------------------------------------------- /src/redux/reducers/configurationPage.ts: -------------------------------------------------------------------------------- 1 | import { 2 | key, 3 | CONFIGURATION_PAGE_SET_LAYOUTS, 4 | ConfigurationPageActions, 5 | IConfigurationPageState 6 | } from "../types/configurationPage"; 7 | import {RootState} from "./index"; 8 | import {ILayoutConfigured} from "../types/home"; 9 | 10 | export const configurationPageSelectors = { 11 | layouts: (state: RootState | any): ILayoutConfigured => state[key].layouts, 12 | }; 13 | 14 | const initialState = { 15 | layouts: { 16 | lg: [], md: [], sm: [], xs: [], xxs: [], 17 | } 18 | }; 19 | 20 | export default function configurationPageReducer(state = initialState, action: ConfigurationPageActions): IConfigurationPageState { 21 | switch (action.type) { 22 | case CONFIGURATION_PAGE_SET_LAYOUTS: 23 | return { 24 | ...state, 25 | layouts: action.layouts 26 | }; 27 | default: 28 | return state; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/redux/reducers/home.ts: -------------------------------------------------------------------------------- 1 | import { 2 | key, 3 | HOME_SET_LAYOUTS, 4 | HOME_ADD_ELEMENT, 5 | HOME_REMOVE_ELEMENT, 6 | ILayout, 7 | HomeActions, 8 | ILayoutConfigured, 9 | ILayoutElement 10 | } from "../types/home"; 11 | import boxes from '../../layouts/box/boxes'; 12 | import guid from '../../utils/math/guid'; 13 | import {RootState} from "./index"; 14 | 15 | export const homeSelectors = { 16 | layouts: (state: RootState): ILayoutConfigured => state[key].layouts, 17 | elements: (state: RootState): ILayoutElement[] => state[key].elements 18 | }; 19 | 20 | const initialState: ILayout = { 21 | layouts: { 22 | lg: [], md: [], sm: [], xs: [], xxs: [], 23 | }, 24 | elements: [] 25 | }; 26 | 27 | export default function homeReducer(state = initialState, action: HomeActions): ILayout { 28 | switch (action.type) { 29 | case HOME_SET_LAYOUTS: 30 | return { 31 | ...state, 32 | layouts: action.layouts 33 | }; 34 | case HOME_ADD_ELEMENT: 35 | const gu = guid(); 36 | const elemToAdd = { i: gu, ...{ ...boxes[action.element] } }; 37 | // elemToAdd.additionalInfo.id = gu; 38 | 39 | return { 40 | ...state, 41 | elements: [...state.elements, elemToAdd] 42 | }; 43 | case HOME_REMOVE_ELEMENT: 44 | const elem = [...state.elements].filter(elemToSel => elemToSel.additionalInfo.boxType === action.element)[0]; 45 | 46 | const layouts = { ...state.layouts }; 47 | Object.keys(layouts).forEach((keyLayout) => { 48 | layouts[keyLayout] = layouts[keyLayout].filter(elemToFilter => elemToFilter.i !== elem.i); 49 | }); 50 | 51 | return { 52 | ...state, 53 | layouts, 54 | elements: [...state.elements].filter(elemL => elemL.i !== elem.i) 55 | }; 56 | default: 57 | return state; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/redux/reducers/index.ts: -------------------------------------------------------------------------------- 1 | import { combineReducers } from '@reduxjs/toolkit'; 2 | 3 | import versionReducer from './version'; 4 | import configurationReducer from './configuration'; 5 | import moduleInfoReducer from './moduleInfo'; 6 | 7 | import notificationsReducer from './notifications'; 8 | import subscriptionsServiceWorkerReducer from "./subscriptionsServiceWorker"; 9 | import homeReducer from "./home"; 10 | import serverStateReducer from "./serverState"; 11 | import webSocketReducer from "./webSocket"; 12 | import deviceMessagesReducer from "./deviceMessages"; 13 | 14 | import configurationPageReducer from "./configurationPage" 15 | import sendReceiveDataPageReducer from "./sendReceiveDataPage" 16 | import resetDeviceReducer from "./resetDevice" 17 | 18 | const rootReducer = combineReducers({ 19 | version: versionReducer, 20 | configuration: configurationReducer, 21 | moduleInfo: moduleInfoReducer, 22 | notifications: notificationsReducer, 23 | subscriptionServiceWorker: subscriptionsServiceWorkerReducer, 24 | home: homeReducer, 25 | serverState: serverStateReducer, 26 | webSocket: webSocketReducer, 27 | deviceMessages: deviceMessagesReducer, 28 | configurationPage: configurationPageReducer, 29 | sendReceiveDataPage: sendReceiveDataPageReducer, 30 | resetDevice: resetDeviceReducer 31 | }); 32 | 33 | export default rootReducer; 34 | 35 | export type RootState = ReturnType 36 | -------------------------------------------------------------------------------- /src/redux/reducers/moduleInfo.ts: -------------------------------------------------------------------------------- 1 | import { 2 | key, 3 | MODULE_INFO_FETCH, 4 | MODULE_INFO_FETCH_CANCEL, 5 | MODULE_INFO_FETCH_FULFILLED, 6 | MODULE_INFO_FETCH_REJECTED, 7 | IModuleInfoState 8 | } from "../types/moduleInfo"; 9 | import {ModuleInfoActions, IModuleInfo} from "../types/moduleInfo"; 10 | import {RootState} from "./index"; 11 | 12 | export const moduleInfoSelectors = { 13 | moduleInfo: (state: RootState | any): IModuleInfo => state[key].moduleInfo, 14 | lastUpdate: (state: RootState): Date | undefined => state.moduleInfo.lastUpdate, 15 | fetchStatus: (state: RootState): string | undefined => state[key].fetchStatus 16 | }; 17 | 18 | // export const moduleInfoInitialState: IModuleInfo = { 19 | // frequency: undefined, 20 | // version: undefined, 21 | // features: undefined 22 | // } 23 | 24 | const initialState: IModuleInfoState = { 25 | // moduleInfo?: undefined, 26 | lastUpdate: undefined, 27 | 28 | isFetching: true, 29 | fetchStatus: `fetching... ${(new Date()).toLocaleString()}`, 30 | 31 | errors: [], 32 | valid: false 33 | }; 34 | 35 | export default function moduleInfoReducer(state = initialState, action: ModuleInfoActions): IModuleInfoState { 36 | switch (action.type) { 37 | case MODULE_INFO_FETCH: 38 | return { 39 | ...state, 40 | isFetching: true, 41 | fetchStatus: `fetching... ${(new Date()).toLocaleString()}`, 42 | moduleInfo: undefined, 43 | lastUpdate: undefined 44 | }; 45 | case MODULE_INFO_FETCH_FULFILLED: 46 | return { 47 | ...state, 48 | moduleInfo: action.moduleInfo, 49 | isFetching: false, 50 | fetchStatus: `Results from ${(new Date()).toLocaleString()}`, 51 | lastUpdate: action.lastUpdate, 52 | valid: true 53 | }; 54 | case MODULE_INFO_FETCH_REJECTED: 55 | // debugger 56 | return { 57 | ...state, 58 | isFetching: false, 59 | fetchStatus: `errored: ${action.err.message}`, 60 | errors: [action.err.message] 61 | }; 62 | case MODULE_INFO_FETCH_CANCEL: 63 | return { 64 | ...state, 65 | isFetching: false, 66 | fetchStatus: 'user cancelled' 67 | }; 68 | default: 69 | return state; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/redux/reducers/resetDevice.ts: -------------------------------------------------------------------------------- 1 | import { 2 | key, 3 | RESET_DEVICE_FETCH, 4 | RESET_DEVICE_FETCH_CANCEL, 5 | RESET_DEVICE_FETCH_FULFILLED, 6 | RESET_DEVICE_FETCH_REJECTED, 7 | IResetDeviceState 8 | } from "../types/resetDevice"; 9 | import {ResetDeviceActions, IStatus} from "../types/resetDevice"; 10 | import {RootState} from "./index"; 11 | 12 | export const resetDeviceSelectors = { 13 | resetDevice: (state: RootState | any): IStatus => state[key].status, 14 | fetchStatus: (state: RootState): string | undefined => state[key].fetchStatus 15 | }; 16 | 17 | // export const resetDeviceInitialState: IResetDevice = { 18 | // frequency: undefined, 19 | // version: undefined, 20 | // features: undefined 21 | // } 22 | 23 | const initialState: IResetDeviceState = { 24 | // resetDevice?: undefined, 25 | lastUpdate: undefined, 26 | 27 | isFetching: false, 28 | fetchStatus: `fetching... ${(new Date()).toLocaleString()}`, 29 | 30 | errors: [], 31 | valid: false 32 | }; 33 | 34 | export default function resetDeviceReducer(state = initialState, action: ResetDeviceActions): IResetDeviceState { 35 | switch (action.type) { 36 | case RESET_DEVICE_FETCH: 37 | return { 38 | ...state, 39 | isFetching: true, 40 | fetchStatus: `fetching... ${(new Date()).toLocaleString()}`, 41 | status: undefined, 42 | lastUpdate: undefined 43 | }; 44 | case RESET_DEVICE_FETCH_FULFILLED: 45 | return { 46 | ...state, 47 | status: action.status, 48 | isFetching: false, 49 | fetchStatus: `Results from ${(new Date()).toLocaleString()}`, 50 | lastUpdate: action.lastUpdate, 51 | valid: true 52 | }; 53 | case RESET_DEVICE_FETCH_REJECTED: 54 | // debugger 55 | return { 56 | ...state, 57 | isFetching: false, 58 | fetchStatus: `errored: ${action.err.message}`, 59 | errors: [action.err.message] 60 | }; 61 | case RESET_DEVICE_FETCH_CANCEL: 62 | return { 63 | ...state, 64 | isFetching: false, 65 | fetchStatus: 'user cancelled' 66 | }; 67 | default: 68 | return state; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/redux/reducers/sendReceiveDataPage.ts: -------------------------------------------------------------------------------- 1 | import { 2 | key, 3 | SEND_RECEIVE_DATA_PAGE_SET_LAYOUTS, 4 | SendReceiveDataPageActions, 5 | ISendReceiveDataPageState 6 | } from "../types/sendReceiveDataPage"; 7 | import {RootState} from "./index"; 8 | import {ILayoutConfigured} from "../types/home"; 9 | 10 | export const sendReceiveDataPageSelectors = { 11 | layouts: (state: RootState | any): ILayoutConfigured => state[key].layouts, 12 | }; 13 | 14 | const initialState = { 15 | layouts: { 16 | lg: [], md: [], sm: [], xs: [], xxs: [], 17 | } 18 | }; 19 | 20 | export default function sendReceiveDataPageReducer(state = initialState, action: SendReceiveDataPageActions): ISendReceiveDataPageState { 21 | switch (action.type) { 22 | case SEND_RECEIVE_DATA_PAGE_SET_LAYOUTS: 23 | return { 24 | ...state, 25 | layouts: action.layouts 26 | }; 27 | default: 28 | return state; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/redux/reducers/subscriptionsServiceWorker.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ISubscriptionsServiceWorkers, 3 | SET_PUSH_NOTIFICATION_IS_SUPPORTED, 4 | SET_SUBSCRIPTION_SERVICE_WORKER, 5 | SET_USER_SUBSCRIBED_TO_PUSH_NOTIFICATION, SubscriptionsServiceWorkerActions 6 | } from "../types/subscriptionsServiceWorker"; 7 | 8 | const initialState: ISubscriptionsServiceWorkers = { 9 | isServiceWorkerSubscribed: false, 10 | registration: null, 11 | isPushNotificationSupported: false, 12 | isUserSubscribedToPushNotification: false 13 | }; 14 | 15 | export default function subscriptionsServiceWorkerReducer (state = initialState, action: SubscriptionsServiceWorkerActions):ISubscriptionsServiceWorkers { 16 | switch (action.type) { 17 | case SET_SUBSCRIPTION_SERVICE_WORKER: 18 | return { 19 | ...state, 20 | isServiceWorkerSubscribed: action.isServiceWorkerSubscribed, 21 | registration: action.registration 22 | }; 23 | case SET_PUSH_NOTIFICATION_IS_SUPPORTED: 24 | return { 25 | ...state, 26 | isPushNotificationSupported: action.isPushNotificationSupported 27 | }; 28 | case SET_USER_SUBSCRIBED_TO_PUSH_NOTIFICATION: 29 | return { 30 | ...state, 31 | isUserSubscribedToPushNotification: action.isUserSubscribedToPushNotification 32 | }; 33 | default: 34 | return state; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /src/redux/reducers/version.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IVersion, SET_VERSION, key, VersionActions, 3 | } from '../types/version'; 4 | import { RootState } from './index'; 5 | 6 | export const versionSelectors = { 7 | appVersion: (state: RootState): string => state[key].version, 8 | appDate: (state: RootState): string => state[key].date, 9 | }; 10 | 11 | const initialState: IVersion = { 12 | version: '0.0.1', 13 | date: '1/1/2000', 14 | }; 15 | 16 | export default function versionReducer(state: IVersion = initialState, action: VersionActions): IVersion { 17 | switch (action.type) { 18 | case SET_VERSION: 19 | return { version: action.payload.version, date: action.payload.date }; 20 | default: 21 | return state; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/redux/reducers/webSocket.ts: -------------------------------------------------------------------------------- 1 | import { 2 | // WEB_SOCKET_OPEN, 3 | // WEB_SOCKET_CLOSE, 4 | WEB_SOCKET_ERROR, 5 | WEB_SOCKET_MESSAGE, 6 | WEB_SOCKET_SEND_MESSAGE, 7 | WEB_SOCKET_CONNECT, 8 | WEB_SOCKET_DISCONNECT, 9 | WebSocketActions, 10 | IWebSocketState, 11 | key, 12 | WEB_SOCKET_CLOSE, WEB_SOCKET_SINGLE_MESSAGE, WEB_SOCKET_RECEIVING_DEVICE_MESSAGE 13 | } from "../types/webSocket"; 14 | import {RootState} from "./index"; 15 | import {IConfiguration} from "../types/configuration"; 16 | 17 | export const webSocketSelectors = { 18 | isConnected: (state: RootState | any): boolean => state[key].isConnected, 19 | singleMessage: (state: RootState | any): boolean => state[key].singleMessage, 20 | receivingDeviceMessages: (state: RootState | any): boolean => state[key].receivingDeviceMessages, 21 | }; 22 | 23 | const initialState = { 24 | messageToSend: '', 25 | isConnected: false, 26 | lastUpdate: null 27 | }; 28 | 29 | export default function webSocketReducer(state = initialState, action: WebSocketActions): IWebSocketState { 30 | switch (action.type) { 31 | case WEB_SOCKET_CONNECT: 32 | return { 33 | ...state, 34 | isConnected: true 35 | }; 36 | case WEB_SOCKET_DISCONNECT: 37 | return { 38 | ...state, 39 | isConnected: false 40 | }; 41 | case WEB_SOCKET_CLOSE: 42 | // debugger 43 | return { 44 | ...state 45 | }; 46 | case WEB_SOCKET_ERROR: 47 | return { 48 | ...state, 49 | error: action.error 50 | }; 51 | case WEB_SOCKET_MESSAGE: 52 | return { 53 | ...state, 54 | message: action.message 55 | }; 56 | case WEB_SOCKET_SEND_MESSAGE: 57 | // debugger 58 | return { 59 | ...state, 60 | messageToSend: action.message 61 | }; 62 | case WEB_SOCKET_SINGLE_MESSAGE: 63 | // debugger 64 | return { 65 | ...state, 66 | singleMessage: action.singleMessage 67 | }; 68 | case WEB_SOCKET_RECEIVING_DEVICE_MESSAGE: 69 | // debugger 70 | return { 71 | ...state, 72 | receivingDeviceMessages: action.receivingDeviceMessages 73 | }; 74 | default: 75 | return state; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/redux/types/configurationPage.ts: -------------------------------------------------------------------------------- 1 | import {Action} from "redux"; 2 | import {INotification} from "./notifications"; 3 | import {ILayoutConfigured, ILayoutElement} from "./home"; 4 | 5 | export const key = 'configurationPage'; 6 | 7 | // action type constants 8 | export const CONFIGURATION_PAGE_SET_LAYOUTS = 'CONFIGURATION_PAGE_SET_LAYOUTS'; 9 | 10 | export const actionTypes = { 11 | CONFIGURATION_PAGE_SET_LAYOUTS 12 | }; 13 | 14 | export interface IConfigurationPageState { 15 | layouts: ILayoutConfigured 16 | } 17 | 18 | class SetConfigurationPageLayout implements Action { 19 | readonly type = CONFIGURATION_PAGE_SET_LAYOUTS; 20 | constructor(public layouts: ILayoutConfigured) {} 21 | } 22 | 23 | export type ConfigurationPageActions = SetConfigurationPageLayout; 24 | -------------------------------------------------------------------------------- /src/redux/types/home.ts: -------------------------------------------------------------------------------- 1 | 2 | // unique key namespace used by combineReducers. 3 | // By convention it will match the directory structure to 4 | // make it easy to locate the src. 5 | // Also action types will prefix with the capitalized version 6 | import {Action} from "redux"; 7 | // import {CONFIGURATION_FIELD_INVALID, IConfiguration} from "./configuration"; 8 | import {INotification} from "./notifications"; 9 | 10 | export const key = 'home'; 11 | 12 | // action type constants 13 | export const HOME_SET_LAYOUTS = 'HOME_SET_LAYOUTS'; 14 | export const HOME_ADD_ELEMENT = 'HOME_ADD_ELEMENT'; 15 | export const HOME_REMOVE_ELEMENT = 'HOME_REMOVE_ELEMENT'; 16 | 17 | export const actionTypes = { 18 | HOME_SET_LAYOUTS, 19 | HOME_ADD_ELEMENT, 20 | HOME_REMOVE_ELEMENT 21 | }; 22 | // "i": string, 23 | export interface ILayoutElement { 24 | i?: string, 25 | id?: string, 26 | additionalInfo: any, 27 | isBounded?: boolean, 28 | isDraggable?: boolean, 29 | isResizable?: boolean, 30 | close?: boolean, 31 | minW: number, 32 | maxW: number, 33 | minH: number, 34 | maxH: number, 35 | w: number, 36 | h: number, 37 | x?: number, 38 | y?: number | null 39 | } 40 | 41 | export interface ILayoutConfigured { 42 | [key: string]: ILayoutElement[] 43 | // , 44 | // [md: string]: ILayoutElement[], 45 | // [sm: string]: ILayoutElement[], 46 | // [xs: string]: ILayoutElement[], 47 | // [xxs: string]: ILayoutElement[], 48 | } 49 | 50 | export interface ILayout { 51 | layouts: ILayoutConfigured, 52 | elements: ILayoutElement[] 53 | } 54 | 55 | class SetHomeLayout implements Action { 56 | readonly type = HOME_SET_LAYOUTS; 57 | constructor(public layouts: ILayoutConfigured) {} 58 | } 59 | 60 | class AddElementToHome implements Action { 61 | readonly type = HOME_ADD_ELEMENT; 62 | constructor(public element: any) {} 63 | } 64 | 65 | class RemoveElementFromHome implements Action { 66 | readonly type = HOME_REMOVE_ELEMENT; 67 | constructor(public element: string) {} 68 | } 69 | 70 | export type HomeActions = SetHomeLayout | AddElementToHome | RemoveElementFromHome; 71 | -------------------------------------------------------------------------------- /src/redux/types/index.ts: -------------------------------------------------------------------------------- 1 | import { VersionActions } from './version'; 2 | import { ConfigurationActions } from './configuration'; 3 | import { ServerStateActions } from "./serverState"; 4 | import { WebSocketActions } from "./webSocket"; 5 | import { NotificationsActions } from "./notifications"; 6 | import {HomeActions} from "./home"; 7 | import {DeviceMessagesActions} from "./deviceMessages"; 8 | import {ConfigurationPageActions} from "./configurationPage"; 9 | import {SendReceiveDataPageActions} from "./sendReceiveDataPage"; 10 | import {ResetDeviceActions} from "./resetDevice"; 11 | 12 | export type AppActions = VersionActions | ConfigurationActions | ServerStateActions | WebSocketActions | 13 | NotificationsActions | HomeActions | DeviceMessagesActions | ConfigurationPageActions | SendReceiveDataPageActions | 14 | ResetDeviceActions; 15 | -------------------------------------------------------------------------------- /src/redux/types/notifications.ts: -------------------------------------------------------------------------------- 1 | // import {Component} from "react"; 2 | import {Action} from "redux"; 3 | 4 | export interface INotification { 5 | title?: string, 6 | message: JSX.Element | JSX.Element[] | string, 7 | variant: string, 8 | autoHide?: number 9 | } 10 | 11 | // unique key namespace used by combineReducers. 12 | // By convention it will match the directory structure to 13 | // make it easy to locate the src. 14 | // Also action types will prefix with the capitalized version 15 | export const key = 'notifications'; 16 | 17 | // action type constants 18 | export const ADD_NOTIFICATION = 'ADD_NOTIFICATION'; 19 | export const SHIFT_NOTIFICATION = 'SHIFT_NOTIFICATION'; 20 | export const GET_CURRENT_NOTIFICATION = 'GET_CURRENT_NOTIFICATION'; 21 | 22 | export const actionTypes = { 23 | ADD_NOTIFICATION, 24 | SHIFT_NOTIFICATION, 25 | GET_CURRENT_NOTIFICATION 26 | }; 27 | 28 | export interface INotificationsState { 29 | current: INotification | null, 30 | queue: INotification[] 31 | } 32 | 33 | class AddNotification implements Action { 34 | readonly type = ADD_NOTIFICATION; 35 | constructor(public notification: INotification) {} 36 | } 37 | 38 | class ShiftNotification implements Action { 39 | readonly type = SHIFT_NOTIFICATION; 40 | } 41 | 42 | class GetCurrentNotification implements Action { 43 | readonly type = GET_CURRENT_NOTIFICATION; 44 | } 45 | 46 | export type NotificationsActions = AddNotification | ShiftNotification | GetCurrentNotification 47 | -------------------------------------------------------------------------------- /src/redux/types/resetDevice.ts: -------------------------------------------------------------------------------- 1 | // unique key namespace used by combineReducers. 2 | // By convention it will match the directory structure to 3 | // make it easy to locate the src. 4 | // Also action types will prefix with the capitalized version 5 | import {Action} from "redux"; 6 | import {TRANSMISSION_POWER_100, TRANSMISSION_POWER_1W} from "./configuration"; 7 | 8 | export const key = 'resetDevice'; 9 | 10 | // action type constants 11 | export const RESET_DEVICE_FETCH = 'RESET_DEVICE_FETCH'; 12 | export const RESET_DEVICE_FETCH_CANCEL = 'RESET_DEVICE_FETCH_CANCEL'; 13 | export const RESET_DEVICE_FETCH_FULFILLED = 'RESET_DEVICE_FETCH_FULFILLED'; 14 | export const RESET_DEVICE_FETCH_REJECTED = 'RESET_DEVICE_FETCH_REJECTED'; 15 | export const RESET_DEVICE_BATTERY_FETCH_FULFILLED = 'RESET_DEVICE_BATTERY_FETCH_FULFILLED'; 16 | export const RESET_DEVICE_WIFI_STRENGHT_FETCH_FULFILLED = 'RESET_DEVICE_WIFI_STRENGHT_FETCH_FULFILLED'; 17 | 18 | export const actionTypes = { 19 | RESET_DEVICE_FETCH, 20 | RESET_DEVICE_FETCH_CANCEL, 21 | RESET_DEVICE_FETCH_FULFILLED, 22 | RESET_DEVICE_FETCH_REJECTED, 23 | RESET_DEVICE_BATTERY_FETCH_FULFILLED, 24 | RESET_DEVICE_WIFI_STRENGHT_FETCH_FULFILLED 25 | }; 26 | 27 | export interface IStatus { 28 | code: number, 29 | error: boolean, 30 | description: string 31 | } 32 | 33 | export interface IResetDeviceState { 34 | status?: IStatus, 35 | lastUpdate?: Date | undefined; 36 | 37 | isFetching: boolean, 38 | fetchStatus?: string, 39 | 40 | errors?: string[], 41 | valid: boolean, 42 | } 43 | 44 | class ResetDeviceFetch implements Action{ 45 | readonly type = RESET_DEVICE_FETCH; 46 | isFetching: boolean = false; 47 | fetchStatus?: string = ''; // `fetching... ${(new Date()).toLocaleString()}`; 48 | lastUpdate?: Date = new Date() 49 | } 50 | class ResetDeviceFetchCancel implements Action { 51 | readonly type = RESET_DEVICE_FETCH_CANCEL; 52 | isFetching: boolean = false; 53 | fetchStatus: string = ''//'user cancelled' 54 | } 55 | class ResetDeviceFetchFulfilled implements Action { 56 | readonly type = RESET_DEVICE_FETCH_FULFILLED; 57 | isFetching: boolean = false; 58 | fetchStatus?: string = '';//`Results from ${(new Date()).toLocaleString()}`; 59 | lastUpdate?: Date = new Date(); 60 | constructor(public status: IStatus) {} 61 | } 62 | class ResetDeviceFetchRejected implements Action { 63 | readonly type = RESET_DEVICE_FETCH_REJECTED; 64 | isFetching: boolean = false; 65 | fetchStatus: string = ''; //`errored: ${action.payload}; 66 | // err: any = {}; 67 | constructor(public err: any) {} 68 | } 69 | 70 | export type ResetDeviceActions = ResetDeviceFetch | ResetDeviceFetchCancel | ResetDeviceFetchFulfilled | 71 | ResetDeviceFetchRejected; 72 | -------------------------------------------------------------------------------- /src/redux/types/sendReceiveDataPage.ts: -------------------------------------------------------------------------------- 1 | import {Action} from "redux"; 2 | import {INotification} from "./notifications"; 3 | import {ILayoutConfigured, ILayoutElement} from "./home"; 4 | 5 | export const key = 'sendReceiveDataPage'; 6 | 7 | // action type constants 8 | export const SEND_RECEIVE_DATA_PAGE_SET_LAYOUTS = 'SEND_RECEIVE_DATA_PAGE_SET_LAYOUTS'; 9 | 10 | export const actionTypes = { 11 | SEND_RECEIVE_DATA_PAGE_SET_LAYOUTS 12 | }; 13 | 14 | export interface ISendReceiveDataPageState { 15 | layouts: ILayoutConfigured 16 | } 17 | 18 | class SetSendReceiveDataPageLayout implements Action { 19 | readonly type = SEND_RECEIVE_DATA_PAGE_SET_LAYOUTS; 20 | constructor(public layouts: ILayoutConfigured) {} 21 | } 22 | 23 | export type SendReceiveDataPageActions = SetSendReceiveDataPageLayout; 24 | -------------------------------------------------------------------------------- /src/redux/types/serverState.ts: -------------------------------------------------------------------------------- 1 | 2 | // unique key namespace used by combineReducers. 3 | // By convention it will match the directory structure to 4 | // make it easy to locate the src. 5 | // Also action types will prefix with the capitalized version 6 | import {Action} from "redux"; 7 | // import {IConfiguration} from "./configuration"; 8 | 9 | export const key = 'serverState'; 10 | 11 | // action type constants 12 | export const SERVER_STATE_FETCH = 'SERVER_STATE_FETCH'; 13 | export const SERVER_STATE_FETCH_CANCEL = 'SERVER_STATE_FETCH_CANCEL'; 14 | export const SERVER_STATE_FETCH_FULFILLED = 'SERVER_STATE_FETCH_FULFILLED'; 15 | export const SERVER_STATE_FETCH_REJECTED = 'SERVER_STATE_FETCH_REJECTED'; 16 | export const SERVER_STATE_BATTERY_FETCH_FULFILLED = 'SERVER_STATE_BATTERY_FETCH_FULFILLED'; 17 | export const SERVER_STATE_WIFI_STRENGHT_FETCH_FULFILLED = 'SERVER_STATE_WIFI_STRENGHT_FETCH_FULFILLED'; 18 | 19 | export const actionTypes = { 20 | SERVER_STATE_FETCH, 21 | SERVER_STATE_FETCH_CANCEL, 22 | SERVER_STATE_FETCH_FULFILLED, 23 | SERVER_STATE_FETCH_REJECTED, 24 | SERVER_STATE_BATTERY_FETCH_FULFILLED, 25 | SERVER_STATE_WIFI_STRENGHT_FETCH_FULFILLED 26 | }; 27 | 28 | export interface IServerState { 29 | data: any; 30 | voltage: number; 31 | signalStrenght: number; 32 | lastUpdate?: Date | undefined | null; 33 | 34 | isFetching: boolean; 35 | fetchStatus?: string; 36 | 37 | err?: any; 38 | error: boolean; 39 | } 40 | 41 | class ServerStateFetch implements Action { 42 | readonly type = SERVER_STATE_FETCH; 43 | isFetching: boolean = false; 44 | fetchStatus?: string = ''; // `fetching... ${(new Date()).toLocaleString()}`; 45 | lastUpdate: Date | null = null; 46 | } 47 | 48 | class ServerStateFetchCancel implements Action { 49 | readonly type = SERVER_STATE_FETCH_CANCEL; 50 | isFetching: boolean = false; 51 | fetchStatus: string = ''//'user cancelled' 52 | } 53 | 54 | class ServerStateFetchFulfilled implements Action { 55 | readonly type = SERVER_STATE_FETCH_FULFILLED; 56 | isFetching: boolean = false; 57 | fetchStatus?: string = '';//`Results from ${(new Date()).toLocaleString()}`; 58 | lastUpdate: Date = new Date(); 59 | constructor(public data: any) {} 60 | } 61 | 62 | class ServerStateBatteryFetchFulfilled implements Action { 63 | readonly type = SERVER_STATE_BATTERY_FETCH_FULFILLED; 64 | voltage: number = 0; 65 | lastUpdate?: Date; 66 | } 67 | 68 | class ServerStateWIFIStrenghtFetchFulfilled implements Action { 69 | readonly type = SERVER_STATE_WIFI_STRENGHT_FETCH_FULFILLED; 70 | signalStrengh: number = 0; 71 | lastUpdate?: Date 72 | } 73 | 74 | class ServerStateFetchRejected implements Action { 75 | readonly type = SERVER_STATE_FETCH_REJECTED; 76 | isFetching: boolean = false; 77 | fetchStatus: string = ''; //`errored: ${action.payload}; 78 | err: object = {}; 79 | error: boolean = true; 80 | } 81 | 82 | export type ServerStateActions = ServerStateFetch | ServerStateBatteryFetchFulfilled | ServerStateFetchCancel | 83 | ServerStateFetchRejected | ServerStateWIFIStrenghtFetchFulfilled | ServerStateFetchFulfilled; 84 | -------------------------------------------------------------------------------- /src/redux/types/subscriptionsServiceWorker.ts: -------------------------------------------------------------------------------- 1 | import {Action} from "redux"; 2 | // import {INotification} from "./notifications"; 3 | 4 | export const key = 'subscriptionsServiceWorker'; 5 | 6 | // action type constants 7 | export const SET_SUBSCRIPTION_SERVICE_WORKER = 'SET_SUBSCRIPTION_SERVICE_WORKER'; 8 | export const SET_PUSH_NOTIFICATION_IS_SUPPORTED = 'SET_PUSH_NOTIFICATION_IS_SUPPORTED'; 9 | export const SET_USER_SUBSCRIBED_TO_PUSH_NOTIFICATION = 'SET_USER_SUBSCRIBED_TO_PUSH_NOTIFICATION'; 10 | 11 | export const actionTypes = { 12 | SET_SUBSCRIPTION_SERVICE_WORKER, 13 | SET_PUSH_NOTIFICATION_IS_SUPPORTED, 14 | SET_USER_SUBSCRIBED_TO_PUSH_NOTIFICATION 15 | }; 16 | 17 | export interface ISubscriptionsServiceWorkers { 18 | isServiceWorkerSubscribed: boolean, 19 | registration: any, 20 | isPushNotificationSupported: boolean, 21 | isUserSubscribedToPushNotification: boolean 22 | } 23 | 24 | class SetServiceWorkerSubscription implements Action { 25 | readonly type = SET_SUBSCRIPTION_SERVICE_WORKER; 26 | constructor(public isServiceWorkerSubscribed: boolean, public registration: any) {}; 27 | } 28 | 29 | class SetPushNotificationSupported implements Action { 30 | readonly type = SET_PUSH_NOTIFICATION_IS_SUPPORTED; 31 | constructor(public isPushNotificationSupported: boolean) {}; 32 | } 33 | 34 | class SetUserSubscribedToPushNotification implements Action { 35 | readonly type = SET_USER_SUBSCRIBED_TO_PUSH_NOTIFICATION; 36 | constructor(public isUserSubscribedToPushNotification: boolean) {} 37 | } 38 | 39 | export type SubscriptionsServiceWorkerActions = SetServiceWorkerSubscription | SetPushNotificationSupported | SetUserSubscribedToPushNotification; 40 | 41 | -------------------------------------------------------------------------------- /src/redux/types/version.ts: -------------------------------------------------------------------------------- 1 | import {Action} from "redux"; 2 | 3 | export interface IVersion { 4 | version: string; 5 | date: string; 6 | } 7 | 8 | export const key = 'version'; 9 | 10 | // action type constants 11 | export const SET_VERSION = 'SET_VERSION'; 12 | 13 | export const actionTypes = { 14 | SET_VERSION, 15 | }; 16 | 17 | class SetVersion implements Action{ 18 | readonly type = SET_VERSION 19 | 20 | constructor(public payload: IVersion) {} 21 | } 22 | export type VersionActions = SetVersion 23 | -------------------------------------------------------------------------------- /src/resources/images/bill.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/bill.jpg -------------------------------------------------------------------------------- /src/resources/images/bill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/bill.png -------------------------------------------------------------------------------- /src/resources/images/favicon/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/android-icon-144x144.png -------------------------------------------------------------------------------- /src/resources/images/favicon/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/android-icon-192x192.png -------------------------------------------------------------------------------- /src/resources/images/favicon/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/android-icon-36x36.png -------------------------------------------------------------------------------- /src/resources/images/favicon/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/android-icon-48x48.png -------------------------------------------------------------------------------- /src/resources/images/favicon/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/android-icon-72x72.png -------------------------------------------------------------------------------- /src/resources/images/favicon/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/android-icon-96x96.png -------------------------------------------------------------------------------- /src/resources/images/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /src/resources/images/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /src/resources/images/favicon/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/favicon-96x96.png -------------------------------------------------------------------------------- /src/resources/images/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/favicon/favicon.ico -------------------------------------------------------------------------------- /src/resources/images/favicon/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /src/resources/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/logo.jpg -------------------------------------------------------------------------------- /src/resources/images/sidebar-solar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/sidebar-solar.jpg -------------------------------------------------------------------------------- /src/resources/images/textures/pattern_type1_inverted_4x4_opacity100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xreef/EByte-LoRa-Manager-React-Redux-Web-Front-End/882bc5aa0bfb6b9a8b5d5c7f510c7dd27526cf9a/src/resources/images/textures/pattern_type1_inverted_4x4_opacity100.png -------------------------------------------------------------------------------- /src/routes/dashboard.tsx: -------------------------------------------------------------------------------- 1 | import Dashboard from '@material-ui/icons/Dashboard'; 2 | // import Person from '@material-ui/icons/Person'; 3 | // 4 | // import CalendarViewDay from '@material-ui/icons/CalendarViewDay'; 5 | // import Today from '@material-ui/icons/Today'; 6 | // import Info from '@material-ui/icons/Info'; 7 | // import Warning from '@material-ui/icons/Warning'; 8 | // import Settings from '@material-ui/icons/Settings'; 9 | 10 | import { FormattedMessage } from 'react-intl'; 11 | import React, {ComponentClass, FunctionComponent} from 'react'; 12 | import { 13 | Home, // Intro, About, //Daily, Historical, InverterInfoState, 14 | } from '../views'; 15 | import {OverridableComponent} from "@material-ui/core/OverridableComponent"; 16 | import {SvgIconTypeMap} from "@material-ui/core"; 17 | import {RouteComponentProps, StaticContext} from "react-router"; 18 | import Settings from "@material-ui/icons/Settings"; 19 | import Satellite from "@material-ui/icons/Message"; 20 | import Person from "@material-ui/icons/Person"; 21 | import Configuration from "../views/Configuration"; 22 | import SendReceiveData from "../views/SendReceiveData"; 23 | 24 | import About from "../views/About"; 25 | // import SendReceiveData from '../views/SendReceiveData'; 26 | 27 | export interface IDashboardRoute { 28 | path: string, 29 | sidebarName: JSX.Element | string, 30 | navbarName: JSX.Element | string, 31 | icon: OverridableComponent, 32 | component: ComponentClass | FunctionComponent | ComponentClass, any>, 33 | 34 | redirect?: boolean, 35 | to?: string 36 | } 37 | export interface IDashboardRouteRedirect { 38 | path: string, 39 | navbarName: JSX.Element | string, 40 | redirect: boolean, 41 | to: string 42 | 43 | component?: ComponentClass | FunctionComponent | ComponentClass, any>, 44 | } 45 | 46 | const dashboardRoutes: Array = [ 47 | { 48 | path: '/home', 49 | sidebarName: , 50 | navbarName: , 51 | icon: Dashboard, 52 | component: Home 53 | }, 54 | { 55 | path: '/configuration', 56 | sidebarName: , 57 | navbarName: , 58 | icon: Settings, // "content_paste", 59 | component: Configuration 60 | }, 61 | { 62 | path: '/sendreceive', 63 | sidebarName: , 64 | navbarName: , 65 | icon: Satellite, // "content_paste", 66 | component: SendReceiveData 67 | }, 68 | { 69 | path: '/about', 70 | sidebarName: 'About', 71 | navbarName: 'About', 72 | icon: Person, 73 | component: About 74 | }, 75 | { 76 | redirect: true, path: '/', to: '/home', navbarName: 'Redirect' 77 | } 78 | ]; 79 | 80 | export default dashboardRoutes; 81 | -------------------------------------------------------------------------------- /src/routes/index.tsx: -------------------------------------------------------------------------------- 1 | import DashboardContainer from "../containers/layouts/DashboardContainer"; 2 | 3 | const indexRoutes = [{ path: "/", component: DashboardContainer }]; 4 | // import Test from "../layouts/Test"; 5 | 6 | // const indexRoutes = [{ path: "/", component: Test }]; 7 | 8 | export default indexRoutes; 9 | -------------------------------------------------------------------------------- /src/service-worker.js: -------------------------------------------------------------------------------- 1 | // Set this to true for production 2 | const doCache = false; 3 | 4 | // Name our cache 5 | const CACHE_NAME = 'ebyte-manager-cache-v1'; 6 | 7 | // Delete old caches that are not our current one! 8 | self.addEventListener('activate', (event) => { 9 | const cacheWhitelist = [CACHE_NAME]; 10 | event.waitUntil( 11 | caches.keys() 12 | .then((keyList) => Promise.all(keyList.map((key) => { 13 | if (!cacheWhitelist.includes(key)) { 14 | console.log(`Deleting cache: ${key}`); 15 | return caches.delete(key); 16 | } 17 | }))), 18 | ); 19 | }); 20 | 21 | // The first time the user starts up the PWA, 'install' is triggered. 22 | self.addEventListener('install', (event) => { 23 | if (doCache) { 24 | event.waitUntil( 25 | caches.open(CACHE_NAME) 26 | .then((cache) => { 27 | // Get the assets manifest so we can see what our js file is named 28 | // This is because webpack hashes it 29 | fetch('asset-manifest.json') 30 | .then((response) => { 31 | response.json(); 32 | }) 33 | .then((assets) => { 34 | // Open a cache and cache our files 35 | // We want to cache the page and the main.js generated by webpack 36 | // We could also cache any static assets like CSS or images 37 | const urlsToCache = [ 38 | '/', 39 | // assets["../ebyte-manager-web.js"] 40 | // ,assets["main.js"] 41 | ]; 42 | cache.addAll(urlsToCache); 43 | console.log('cached'); 44 | }); 45 | }), 46 | ); 47 | } 48 | }); 49 | 50 | // When the webpage goes to fetch files, we intercept that request and serve up the matching files 51 | // if we have them 52 | self.addEventListener('fetch', (event) => { 53 | if (doCache) { 54 | event.respondWith( 55 | caches.match(event.request).then((response) => response || fetch(event.request)), 56 | ); 57 | } 58 | }); 59 | 60 | self.addEventListener('install', () => self.skipWaiting()); 61 | self.addEventListener('activate', () => self.clients.claim()); 62 | -------------------------------------------------------------------------------- /src/settings-prod.json: -------------------------------------------------------------------------------- 1 | var settings = {"localRestPort":8080, "localWSPort":8081}; 2 | -------------------------------------------------------------------------------- /src/settings.json: -------------------------------------------------------------------------------- 1 | var settings = {"localIP":"192.168.1.127", "localRestPort":8080, "localWSPort":8081}; 2 | -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /src/utils/canvas/fillFlatGradientOnReference.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by renzo on 20/04/2017. 3 | */ 4 | let fillFlatGradientOnReference = (ctx, height, gradientThreshold, fillColorUp, fillColorDown) => { 5 | var fillStyle; 6 | 7 | if (gradientThreshold < 0) { 8 | fillStyle = fillColorDown; 9 | } else if (gradientThreshold > 1) { 10 | fillStyle = fillColorUp; 11 | } else { 12 | var offset = 0.0; 13 | if (gradientThreshold >= 1) offset = 0; 14 | fillStyle=ctx.createLinearGradient(0,0,0,height); 15 | fillStyle.addColorStop(0,fillColorUp); 16 | fillStyle.addColorStop(gradientThreshold,fillColorUp); 17 | fillStyle.addColorStop(gradientThreshold + offset,fillColorDown); 18 | fillStyle.addColorStop(1,fillColorDown); 19 | } 20 | 21 | return fillStyle; 22 | } 23 | export default fillFlatGradientOnReference; 24 | 25 | let fillFlatGradientOnReferenceToPoint = (ctx, {x1, y1, x2, y2}, gradientThreshold, fillColorUp, fillColorDown) => { 26 | var fillStyle; 27 | 28 | if (gradientThreshold < 0) { 29 | fillStyle = fillColorDown; 30 | } else if (gradientThreshold > 1) { 31 | fillStyle = fillColorUp; 32 | } else { 33 | var offset = 0.0; 34 | if (gradientThreshold >= 1) offset = 0; 35 | fillStyle=ctx.createLinearGradient(x1, y1, x2, y2); 36 | fillStyle.addColorStop(0,fillColorUp); 37 | fillStyle.addColorStop(gradientThreshold,fillColorUp); 38 | fillStyle.addColorStop(gradientThreshold + offset,fillColorDown); 39 | fillStyle.addColorStop(1,fillColorDown); 40 | } 41 | 42 | return fillStyle; 43 | } 44 | export { 45 | fillFlatGradientOnReference, 46 | fillFlatGradientOnReferenceToPoint 47 | }; -------------------------------------------------------------------------------- /src/utils/canvas/fillGradientOnReference.js: -------------------------------------------------------------------------------- 1 | let fillGradientOnReference = (ctx, height, gradientThreshold, fillColorUp, fillColorMiddleUp, fillColorMiddleDown, fillColorDown) => { 2 | let gradi = ctx.createLinearGradient(0, 0, 0, height); 3 | 4 | var offset = 0.0; 5 | 6 | if ( gradientThreshold >= 1 ) 7 | { 8 | gradi.addColorStop( 0, fillColorUp ); 9 | gradi.addColorStop( 1, fillColorMiddleUp ); 10 | } 11 | else if ( gradientThreshold <= 0 ) 12 | { 13 | gradi.addColorStop( 0, fillColorMiddleDown ); 14 | gradi.addColorStop( 1, fillColorDown ); 15 | } 16 | else 17 | { 18 | gradi.addColorStop( 0, fillColorUp ); 19 | gradi.addColorStop( gradientThreshold, fillColorMiddleUp ); 20 | gradi.addColorStop( gradientThreshold + offset, fillColorMiddleDown ); 21 | gradi.addColorStop( 1, fillColorDown ); 22 | } 23 | 24 | return gradi; 25 | }; 26 | export default fillGradientOnReference; 27 | 28 | let fillGradientOnReferencePoint = (ctx, {x1, y1, x2, y2}, gradientThreshold, fillColorUp, fillColorMiddleUp, fillColorMiddleDown, fillColorDown) => { 29 | let gradi = ctx.createLinearGradient(x1, y1, x2, y2); 30 | 31 | var offset = 0.0; 32 | 33 | if ( gradientThreshold >= 1 ) 34 | { 35 | gradi.addColorStop( 0, fillColorUp ); 36 | gradi.addColorStop( 1, fillColorMiddleUp ); 37 | } 38 | else if ( gradientThreshold <= 0 ) 39 | { 40 | gradi.addColorStop( 0, fillColorMiddleDown ); 41 | gradi.addColorStop( 1, fillColorDown ); 42 | } 43 | else 44 | { 45 | gradi.addColorStop( 0, fillColorUp ); 46 | gradi.addColorStop( gradientThreshold, fillColorMiddleUp ); 47 | gradi.addColorStop( gradientThreshold + offset, fillColorMiddleDown ); 48 | gradi.addColorStop( 1, fillColorDown ); 49 | } 50 | 51 | return gradi; 52 | }; 53 | let fillLinearGradientOnReferencePoint = (ctx, {x1, y1, x2, y2}, gradientThreshold, fillColorUp, fillColorDown) => { 54 | let gradi = ctx.createLinearGradient(x1, y1, x2, y2); 55 | 56 | var offset = 0.0; 57 | 58 | if ( gradientThreshold >= 1 ) 59 | { 60 | gradi.addColorStop( 0, fillColorUp ); 61 | gradi.addColorStop( 1, fillColorUp ); 62 | } 63 | else if ( gradientThreshold <= 0 ) 64 | { 65 | gradi.addColorStop( 0, fillColorDown ); 66 | gradi.addColorStop( 1, fillColorDown ); 67 | } 68 | else 69 | { 70 | gradi.addColorStop( 0, fillColorUp ); 71 | gradi.addColorStop( 1, fillColorDown ); 72 | } 73 | 74 | return gradi; 75 | }; 76 | export { 77 | fillGradientOnReference, 78 | fillGradientOnReferencePoint, 79 | fillLinearGradientOnReferencePoint 80 | }; -------------------------------------------------------------------------------- /src/utils/canvas/index.js: -------------------------------------------------------------------------------- 1 | import fillFlatGradientOnReference from "./fillFlatGradientOnReference"; 2 | import fillGradientOnReference from "./fillGradientOnReference"; 3 | import {fillFlatGradientOnReferenceToPoint} from "./fillFlatGradientOnReference"; 4 | import {fillGradientOnReferencePoint, fillLinearGradientOnReferencePoint} from "./fillGradientOnReference"; 5 | import loadImage from "./loadImage"; 6 | 7 | export { 8 | fillFlatGradientOnReference, 9 | fillGradientOnReference, 10 | fillLinearGradientOnReferencePoint, 11 | 12 | fillFlatGradientOnReferenceToPoint, 13 | fillGradientOnReferencePoint, 14 | 15 | loadImage 16 | }; 17 | -------------------------------------------------------------------------------- /src/utils/canvas/loadImage.js: -------------------------------------------------------------------------------- 1 | const loadImage = function (src, callback) { 2 | const img = new Image(); 3 | img.onload = function () { 4 | if (callback) callback(img); 5 | }; 6 | img.src = src; 7 | return img; 8 | }; 9 | export default loadImage; 10 | -------------------------------------------------------------------------------- /src/utils/custom_function/deepmerge.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by renzo on 05/07/2017. 3 | */ 4 | function isMergeableObject(val) { 5 | var nonNullObject = val && typeof val === 'object' 6 | 7 | return nonNullObject 8 | && Object.prototype.toString.call(val) !== '[object RegExp]' 9 | && Object.prototype.toString.call(val) !== '[object Date]' 10 | } 11 | 12 | function emptyTarget(val) { 13 | return Array.isArray(val) ? [] : {} 14 | } 15 | 16 | function cloneIfNecessary(value, optionsArgument) { 17 | var clone = optionsArgument && optionsArgument.clone === true 18 | return (clone && isMergeableObject(value)) ? deepmerge(emptyTarget(value), value, optionsArgument) : value 19 | } 20 | 21 | function defaultArrayMerge(target, source, optionsArgument) { 22 | var destination = target.slice(0, (source && source.lenght>0)?source.length-1:0); 23 | source.forEach(function(e, i) { 24 | if (typeof destination[i] === 'undefined') { 25 | destination[i] = cloneIfNecessary(e, optionsArgument) 26 | } else if (isMergeableObject(e)) { 27 | destination[i] = deepmerge(target[i], e, optionsArgument) 28 | } else if (target.indexOf(e) === -1) { 29 | destination.push(cloneIfNecessary(e, optionsArgument)) 30 | } 31 | }) 32 | return destination 33 | } 34 | 35 | function mergeObject(target, source, optionsArgument) { 36 | var destination = {} 37 | if (isMergeableObject(target)) { 38 | Object.keys(target).forEach(function (key) { 39 | destination[key] = cloneIfNecessary(target[key], optionsArgument) 40 | }) 41 | } 42 | Object.keys(source).forEach(function (key) { 43 | if (!isMergeableObject(source[key]) || !target[key]) { 44 | destination[key] = cloneIfNecessary(source[key], optionsArgument) 45 | } else { 46 | destination[key] = deepmerge(target[key], source[key], optionsArgument) 47 | } 48 | }) 49 | return destination 50 | } 51 | 52 | function deepmerge(target, source, optionsArgument) { 53 | var array = Array.isArray(source); 54 | var options = optionsArgument || { arrayMerge: defaultArrayMerge }; 55 | var arrayMerge = options.arrayMerge || defaultArrayMerge; 56 | 57 | if (array) { 58 | return Array.isArray(target) ? arrayMerge(target, source, optionsArgument) : cloneIfNecessary(source, optionsArgument) 59 | } else { 60 | return mergeObject(target, source, optionsArgument) 61 | } 62 | } 63 | 64 | deepmerge.all = function deepmergeAll(array, optionsArgument) { 65 | if (!Array.isArray(array) || array.length < 2) { 66 | throw new Error('first argument should be an array with at least two elements') 67 | } 68 | 69 | // we are sure there are at least 2 values, so it is safe to have no initial value 70 | return array.reduce(function(prev, next) { 71 | return deepmerge(prev, next, optionsArgument) 72 | }) 73 | } 74 | 75 | export default deepmerge; -------------------------------------------------------------------------------- /src/utils/custom_function/enummap.js: -------------------------------------------------------------------------------- 1 | export default function enummap(enumToConvert){ 2 | var mapGenerated = {}; 3 | for (var i = 0;i<(Object.keys(enumToConvert).length/2);i++){ 4 | mapGenerated[Object.keys(enumToConvert)[i]]=Object.values(enumToConvert)[i]; 5 | } 6 | return mapGenerated; 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/date/dates.js: -------------------------------------------------------------------------------- 1 | // Source: http://stackoverflow.com/questions/497790 2 | const dates = { 3 | convert(d) { 4 | // Converts the date in d to a date-object. The input can be: 5 | // a date object: returned without modification 6 | // an array : Interpreted as [year,month,day]. NOTE: month is 0-11. 7 | // a number : Interpreted as number of milliseconds 8 | // since 1 Jan 1970 (a timestamp) 9 | // a string : Any format supported by the javascript engine, like 10 | // "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc. 11 | // an object : Interpreted as an object with year, month and date 12 | // attributes. **NOTE** month is 0-11. 13 | return ( 14 | d.constructor === Date ? d 15 | : d.constructor === Array ? new Date(d[0], d[1], d[2]) 16 | : d.constructor === Number ? new Date(d) 17 | : d.constructor === String ? new Date(d) 18 | : typeof d === 'object' ? new Date(d.year, d.month, d.date) 19 | : NaN 20 | ); 21 | }, 22 | compare(a, b) { 23 | // Compare two dates (could be of any type supported by the convert 24 | // function above) and returns: 25 | // -1 : if a < b 26 | // 0 : if a = b 27 | // 1 : if a > b 28 | // NaN : if a or b is an illegal date 29 | // NOTE: The code inside isFinite does an assignment (=). 30 | return ( 31 | isFinite(a = this.convert(a).valueOf()) 32 | && isFinite(b = this.convert(b).valueOf()) 33 | ? (a > b) - (a < b) 34 | : NaN 35 | ); 36 | }, 37 | inRange(d, start, end) { 38 | // Checks if date in d is between dates in start and end. 39 | // Returns a boolean or NaN: 40 | // true : if d is between start and end (inclusive) 41 | // false : if d is before start or after end 42 | // NaN : if one or more of the dates is illegal. 43 | // NOTE: The code inside isFinite does an assignment (=). 44 | return ( 45 | isFinite(d = this.convert(d).valueOf()) 46 | && isFinite(start = this.convert(start).valueOf()) 47 | && isFinite(end = this.convert(end).valueOf()) 48 | ? start <= d && d <= end 49 | : NaN 50 | ); 51 | } 52 | }; 53 | export default dates; 54 | -------------------------------------------------------------------------------- /src/utils/localStorage.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /** 3 | * Created by renzo on 19/05/2017. 4 | */ 5 | 6 | export const loadState = (stateName) => { 7 | try { 8 | const serializedState = localStorage.getItem(stateName); 9 | if (serializedState === null) { 10 | return undefined; 11 | } 12 | return JSON.parse(serializedState); 13 | } catch (err) { 14 | return undefined; 15 | } 16 | }; 17 | 18 | export const saveState = (stateName, state) => { 19 | try { 20 | const serializedState = JSON.stringify(state); 21 | localStorage.setItem(stateName, serializedState); 22 | } catch (err) { 23 | throw err; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /src/utils/locale/DSTs.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | id: 0, code: 'GMT', description: 'Standard GMT' 4 | }, 5 | { 6 | id: 1, code: 'AETZ', description: 'Australia Eastern Time Zone (Sydney, Melbourne)' 7 | }, 8 | { 9 | id: 2, code: 'CET', description: 'Central European Time (Frankfurt, Paris)' 10 | }, 11 | { 12 | id: 3, code: 'MSK', description: 'Moscow Standard Time (MSK, does not observe DST)' 13 | }, 14 | { 15 | id: 4, code: 'UK', description: 'United Kingdom (London, Belfast)' 16 | }, 17 | { 18 | id: 5, code: 'USCTZ', description: 'US Central Time Zone (Chicago, Houston)' 19 | }, 20 | { 21 | id: 6, code: 'USMTZ', description: 'US Mountain Time Zone (Denver, Salt Lake City)' 22 | }, 23 | { 24 | id: 7, code: 'ARIZONA', description: 'Arizona is US Mountain Time Zone but does not use DST' 25 | }, 26 | { 27 | id: 8, code: 'UTC', description: 'UTC' 28 | } 29 | ]; 30 | -------------------------------------------------------------------------------- /src/utils/locale/date/ca-ES.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %e de %B de %Y, %X", 3 | "date": "%d/%m/%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte"], 7 | "shortDays": ["dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds."], 8 | "months": ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"], 9 | "shortMonths": ["gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des."] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/cs-CZ.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A,%e.%B %Y, %X", 3 | "date": "%-d.%-m.%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["neděle", "pondělí", "úterý", "středa", "čvrtek", "pátek", "sobota"], 7 | "shortDays": ["ne.", "po.", "út.", "st.", "čt.", "pá.", "so."], 8 | "months": ["leden", "únor", "březen", "duben", "květen", "červen", "červenec", "srpen", "září", "říjen", "listopad", "prosinec"], 9 | "shortMonths": ["led", "úno", "břez", "dub", "kvě", "čer", "červ", "srp", "zář", "říj", "list", "pros"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/de-CH.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, der %e. %B %Y, %X", 3 | "date": "%d.%m.%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], 7 | "shortDays": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], 8 | "months": ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], 9 | "shortMonths": ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/de-DE.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, der %e. %B %Y, %X", 3 | "date": "%d.%m.%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], 7 | "shortDays": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], 8 | "months": ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], 9 | "shortMonths": ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/en-CA.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%a %b %e %X %Y", 3 | "date": "%Y-%m-%d", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], 7 | "shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 8 | "months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], 9 | "shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/en-GB.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%a %e %b %X %Y", 3 | "date": "%d/%m/%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], 7 | "shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 8 | "months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], 9 | "shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%x, %X", 3 | "date": "%-m/%-d/%Y", 4 | "time": "%-I:%M:%S %p", 5 | "periods": ["AM", "PM"], 6 | "days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], 7 | "shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], 8 | "months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], 9 | "shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/es-ES.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %e de %B de %Y, %X", 3 | "date": "%d/%m/%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"], 7 | "shortDays": ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"], 8 | "months": ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], 9 | "shortMonths": ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/es-MX.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%x, %X", 3 | "date": "%d/%m/%Y", 4 | "time": "%-I:%M:%S %p", 5 | "periods": ["AM", "PM"], 6 | "days": ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"], 7 | "shortDays": ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"], 8 | "months": ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], 9 | "shortMonths": ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/fi-FI.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %-d. %Bta %Y klo %X", 3 | "date": "%-d.%-m.%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["a.m.", "p.m."], 6 | "days": ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"], 7 | "shortDays": ["Su", "Ma", "Ti", "Ke", "To", "Pe", "La"], 8 | "months": ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"], 9 | "shortMonths": ["Tammi", "Helmi", "Maalis", "Huhti", "Touko", "Kesä", "Heinä", "Elo", "Syys", "Loka", "Marras", "Joulu"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/fr-CA.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%a %e %b %Y %X", 3 | "date": "%Y-%m-%d", 4 | "time": "%H:%M:%S", 5 | "periods": ["", ""], 6 | "days": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], 7 | "shortDays": ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"], 8 | "months": ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], 9 | "shortMonths": ["jan", "fév", "mar", "avr", "mai", "jui", "jul", "aoû", "sep", "oct", "nov", "déc"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/fr-FR.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, le %e %B %Y, %X", 3 | "date": "%d/%m/%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], 7 | "shortDays": ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], 8 | "months": ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], 9 | "shortMonths": ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/he-IL.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %e ב%B %Y %X", 3 | "date": "%d.%m.%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת"], 7 | "shortDays": ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"], 8 | "months": ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"], 9 | "shortMonths": ["ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/hu-HU.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%Y. %B %-e., %A %X", 3 | "date": "%Y. %m. %d.", 4 | "time": "%H:%M:%S", 5 | "periods": ["de.", "du."], 6 | "days": ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"], 7 | "shortDays": ["V", "H", "K", "Sze", "Cs", "P", "Szo"], 8 | "months": ["január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"], 9 | "shortMonths": ["jan.", "feb.", "már.", "ápr.", "máj.", "jún.", "júl.", "aug.", "szept.", "okt.", "nov.", "dec."] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/it-IT.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A %e %B %Y, %X", 3 | "date": "%d/%m/%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"], 7 | "shortDays": ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"], 8 | "months": ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"], 9 | "shortMonths": ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/ja-JP.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%Y %b %e %a %X", 3 | "date": "%Y/%m/%d", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"], 7 | "shortDays": ["日", "月", "火", "水", "木", "金", "土"], 8 | "months": ["睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走"], 9 | "shortMonths": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/ko-KR.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%Y/%m/%d %a %X", 3 | "date": "%Y/%m/%d", 4 | "time": "%H:%M:%S", 5 | "periods": ["오전", "오후"], 6 | "days": ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"], 7 | "shortDays": ["일", "월", "화", "수", "목", "금", "토"], 8 | "months": ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], 9 | "shortMonths": ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/mk-MK.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %e %B %Y г. %X", 3 | "date": "%d.%m.%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["недела", "понеделник", "вторник", "среда", "четврток", "петок", "сабота"], 7 | "shortDays": ["нед", "пон", "вто", "сре", "чет", "пет", "саб"], 8 | "months": ["јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"], 9 | "shortMonths": ["јан", "фев", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "ное", "дек"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/nl-NL.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%a %e %B %Y %T", 3 | "date": "%d-%m-%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], 7 | "shortDays": ["zo", "ma", "di", "wo", "do", "vr", "za"], 8 | "months": ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], 9 | "shortMonths": ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/pl-PL.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %e %B %Y, %X", 3 | "date": "%d/%m/%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"], 7 | "shortDays": ["Niedz.", "Pon.", "Wt.", "Śr.", "Czw.", "Pt.", "Sob."], 8 | "months": ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"], 9 | "shortMonths": ["Stycz.", "Luty", "Marz.", "Kwie.", "Maj", "Czerw.", "Lipc.", "Sierp.", "Wrz.", "Paźdz.", "Listop.", "Grudz."] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/pt-BR.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %e de %B de %Y. %X", 3 | "date": "%d/%m/%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"], 7 | "shortDays": ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"], 8 | "months": ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], 9 | "shortMonths": ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/ru-RU.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %e %B %Y г. %X", 3 | "date": "%d.%m.%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["AM", "PM"], 6 | "days": ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"], 7 | "shortDays": ["вс", "пн", "вт", "ср", "чт", "пт", "сб"], 8 | "months": ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"], 9 | "shortMonths": ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/sv-SE.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A den %d %B %Y %X", 3 | "date": "%Y-%m-%d", 4 | "time": "%H:%M:%S", 5 | "periods": ["fm", "em"], 6 | "days": ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"], 7 | "shortDays": ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"], 8 | "months": ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"], 9 | "shortMonths": ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/uk-UA.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%A, %e %B %Y р. %X", 3 | "date": "%d.%m.%Y", 4 | "time": "%H:%M:%S", 5 | "periods": ["дп", "пп"], 6 | "days": ["неділя", "понеділок", "вівторок", "середа", "четвер", "п'ятниця", "субота"], 7 | "shortDays": ["нд", "пн", "вт", "ср", "чт", "пт", "сб"], 8 | "months": ["січня", "лютого", "березня", "квітня", "травня", "червня", "липня", "серпня", "вересня", "жовтня", "листопада", "грудня"], 9 | "shortMonths": ["січ.", "лют.", "бер.", "квіт.", "трав.", "черв.", "лип.", "серп.", "вер.", "жовт.", "лист.", "груд."] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/date/zh-CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "dateTime": "%x %A %X", 3 | "date": "%Y年%-m月%-d日", 4 | "time": "%H:%M:%S", 5 | "periods": ["上午", "下午"], 6 | "days": ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], 7 | "shortDays": ["周日", "周一", "周二", "周三", "周四", "周五", "周六"], 8 | "months": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], 9 | "shortMonths": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"] 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-001.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", ""], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-AE.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u062f\u002e\u0625\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-BH.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u062f\u002e\u0628\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-DJ.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["\u200f\u0046\u0064\u006a ", ""], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-DZ.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u002c", 3 | "thousands": "\u002e", 4 | "grouping": [3], 5 | "currency": ["\u062f\u002e\u062c\u002e ", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-EG.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u062c\u002e\u0645\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-EH.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u002e", 3 | "thousands": "\u002c", 4 | "grouping": [3], 5 | "currency": ["\u062f\u002e\u0645\u002e ", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-ER.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["\u004e\u0066\u006b ", ""], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-IL.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["\u20aa ", ""], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-IQ.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u062f\u002e\u0639\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-JO.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u062f\u002e\u0623\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-KM.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u0641\u002e\u062c\u002e\u0642\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-KW.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u062f\u002e\u0643\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-LB.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u0644\u002e\u0644\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-LY.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u002c", 3 | "thousands": "\u002e", 4 | "grouping": [3], 5 | "currency": ["\u062f\u002e\u0644\u002e ", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-MA.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u002c", 3 | "thousands": "\u002e", 4 | "grouping": [3], 5 | "currency": ["\u062f\u002e\u0645\u002e ", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-MR.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u0623\u002e\u0645\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-OM.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u0631\u002e\u0639\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-PS.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["\u20aa ", ""], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-QA.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u0631\u002e\u0642\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-SA.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u0631\u002e\u0633\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-SD.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u062c\u002e\u0633\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-SO.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["\u200f\u0053 ", ""], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-SS.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["\u00a3 ", ""], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-SY.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u0644\u002e\u0633\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-TD.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["\u200f\u0046\u0043\u0046\u0041 ", ""], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-TN.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u002c", 3 | "thousands": "\u002e", 4 | "grouping": [3], 5 | "currency": ["\u062f\u002e\u062a\u002e ", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/ar-YE.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": "\u066b", 3 | "thousands": "\u066c", 4 | "grouping": [3], 5 | "currency": ["", " \u0631\u002e\u0649\u002e"], 6 | "numerals" : ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"] 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/ca-ES.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0€"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/cs-CZ.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": "\u00a0", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0Kč"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/de-CH.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": "'", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0CHF"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/de-DE.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0€"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/en-CA.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3], 5 | "currency": ["$", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/en-GB.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3], 5 | "currency": ["£", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/en-IN.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3, 2, 2, 2, 2, 2, 2, 2, 2, 2], 5 | "currency": ["₹", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3], 5 | "currency": ["$", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/es-ES.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0€"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/es-MX.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3], 5 | "currency": ["$", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/fi-FI.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": "\u00a0", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0€"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/fr-CA.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": "\u00a0", 4 | "grouping": [3], 5 | "currency": ["", "$"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/fr-FR.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0€"], 6 | "percent": "\u202f%" 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/locale/number/he-IL.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3], 5 | "currency": ["₪", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/hu-HU.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": "\u00a0", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0Ft"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/it-IT.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["€", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/ja-JP.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3], 5 | "currency": ["", "円"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/ko-KR.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3], 5 | "currency": ["₩", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/mk-MK.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0ден."] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/nl-NL.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["€\u00a0", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/pl-PL.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["", "zł"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/pt-BR.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": ".", 4 | "grouping": [3], 5 | "currency": ["R$", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/ru-RU.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": "\u00a0", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0руб."] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/sv-SE.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": "\u00a0", 4 | "grouping": [3], 5 | "currency": ["", "SEK"] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/uk-UA.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ",", 3 | "thousands": "\u00a0", 4 | "grouping": [3], 5 | "currency": ["", "\u00a0₴."] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/locale/number/zh-CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "decimal": ".", 3 | "thousands": ",", 4 | "grouping": [3], 5 | "currency": ["¥", ""] 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/math/getReferenceHeight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by renzo on 20/04/2017. 3 | */ 4 | let getReferenceHeight = (reference, minDomain, maxDomain, minRange, maxRange) =>{ 5 | var height = minRange; 6 | var yn; 7 | 8 | let stop = reference; 9 | if (stop > maxDomain) yn = maxRange; 10 | else if (stop < minDomain) yn = minRange; 11 | else yn = height - ((stop - minDomain) / (maxDomain - minDomain) * (minRange - maxRange)); 12 | 13 | return yn; 14 | } 15 | export default getReferenceHeight; -------------------------------------------------------------------------------- /src/utils/math/guid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by renzo on 20/04/2017. 3 | */ 4 | let guid = () => { 5 | function s4() { 6 | return Math.floor((1 + Math.random()) * 0x10000) 7 | .toString(16) 8 | .substring(1); 9 | } 10 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' + 11 | s4() + '-' + s4() + s4() + s4(); 12 | } 13 | 14 | export default guid; -------------------------------------------------------------------------------- /src/utils/math/index.js: -------------------------------------------------------------------------------- 1 | import guid from "./guid"; 2 | import getReferenceHeight from "./getReferenceHeight" 3 | 4 | export { 5 | guid, 6 | getReferenceHeight, 7 | }; 8 | -------------------------------------------------------------------------------- /src/utils/serviceWorker/homeScreen.js: -------------------------------------------------------------------------------- 1 | export const addToHomeScreen = (deferredPrompt, callBack) => { 2 | // let {deferredPrompt} = this.state.serviceWorker; 3 | deferredPrompt.prompt(); // Wait for the user to respond to the prompt 4 | deferredPrompt.userChoice.then(function(choiceResult){ 5 | if (choiceResult.outcome === 'accepted') { 6 | console.log('User accepted to install app'); 7 | 8 | callBack( { 9 | exitStatus: true, 10 | variant: 'success', 11 | message: 'User accepted to install app', 12 | title: 'User accepted to install app' 13 | }); 14 | } else { 15 | console.log('User not accepted to install app'); 16 | 17 | callBack( { 18 | exitStatus: false, 19 | variant: 'warning', 20 | message: 'User not accepted to install app', 21 | title: 'User not accepted to install app' 22 | }); 23 | } 24 | // deferredPrompt = null; 25 | }); 26 | }; 27 | -------------------------------------------------------------------------------- /src/utils/serviceWorker/subscribeServiceWorker.js: -------------------------------------------------------------------------------- 1 | export const subscribeServiceWorker = (callBack) => { 2 | if ('serviceWorker' in navigator) { 3 | window.addEventListener('load', () => { 4 | navigator.serviceWorker.register('service-worker.js').then((registration) => { 5 | callBack( 6 | { 7 | variant: 'info', 8 | message: `ServiceWorker registration successful with scope: ${registration.scope}`, 9 | title: 'ServiceWorker registered', 10 | exitStatus: true, 11 | registration 12 | } 13 | ); 14 | }, (err) => { 15 | // registration failed :( 16 | console.log('ServiceWorker registration failed: ', err); 17 | callBack( 18 | { 19 | variant: 'error', 20 | message: `ServiceWorker registration failed: ${err}`, 21 | title: 'ServiceWorker registration failed', 22 | exitStatus: false, 23 | registration: null 24 | } 25 | ); 26 | }).catch((err) => { 27 | console.log(err); 28 | callBack( 29 | { 30 | variant: 'error', 31 | message: `ServiceWorker registration failed: ${err}`, 32 | title: 'ServiceWorker registration failed', 33 | exitStatus: false, 34 | registration: null 35 | } 36 | ); 37 | }); 38 | }); 39 | } else { 40 | console.log('Service Worker not present'); 41 | callBack( 42 | { 43 | variant: 'error', 44 | message: 'ServiceWorker not found', 45 | title: 'ServiceWorker registration failed', 46 | exitStatus: false, 47 | registration: null 48 | } 49 | ); 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /src/views/About.tsx: -------------------------------------------------------------------------------- 1 | import React, {FunctionComponent} from "react"; 2 | import AboutBox from "../layouts/box/AboutBox"; 3 | import GridContainer from "../component/grid/GridContainer"; 4 | import GridItem from "../component/grid/GridItem"; 5 | import AboutProgramBox from "../layouts/box/AboutProgramBox"; 6 | import AboutLibraryBox from "../layouts/box/AboutLibraryBox"; 7 | 8 | const About: FunctionComponent = () => ( 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ); 21 | 22 | // export default About; 23 | export default About; 24 | -------------------------------------------------------------------------------- /src/views/Home.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | // import PropTypes from 'prop-types'; 4 | import ResponsiveGrid from '../component/responsiveGrid/ResponsiveGrid'; 5 | 6 | import { 7 | setHomeLayout 8 | } from "../redux/actions"; 9 | import { homeSelectors } from '../redux/reducers/home'; 10 | import boxes from '../layouts/box/boxes'; 11 | // import {ILayoutConfigured, ILayoutElement} from "../redux/types/home"; 12 | // import {AppActions} from "../redux/types"; 13 | import {RootState} from "../redux/reducers"; 14 | import {ILayoutElement} from "../redux/types/home"; 15 | // import {versionSelectors} from "../redux/reducers/version"; 16 | // import {configurationFetch, setVersion} from "../redux/actions"; 17 | 18 | // interface HomeProps { 19 | // layouts: ILayoutConfigured, 20 | // elements: ILayoutElement[], 21 | // 22 | // saveLayouts: AppActions | Function 23 | // } 24 | // 25 | interface OwnProps { 26 | 27 | } 28 | // 29 | // type Props = StateProps & DispatchProps & OwnProps 30 | 31 | const mapStateToProps = (state: RootState/*, ownProps*/) => ({ 32 | layouts: homeSelectors.layouts(state), 33 | elements: homeSelectors.elements(state).map((elementHS: ILayoutElement) => { 34 | const eHS = { ...elementHS }; 35 | eHS.additionalInfo.classObj = boxes[eHS.additionalInfo.boxType].additionalInfo.classObj; 36 | eHS.additionalInfo.defaultProps = boxes[eHS.additionalInfo.boxType].additionalInfo.defaultProps; 37 | return eHS; 38 | }) 39 | }); 40 | 41 | const mapDispatchToProps = { 42 | saveLayouts: setHomeLayout 43 | }; 44 | 45 | type StateProps = ReturnType 46 | type DispatchProps = typeof mapDispatchToProps 47 | 48 | type HomeProps = StateProps & DispatchProps & OwnProps 49 | 50 | 51 | class Home extends React.Component { 52 | // constructor(props) { 53 | // super(props); 54 | // } 55 | public static defaultProps: HomeProps = { 56 | layouts: { 57 | lg: [], md: [], sm: [], xs: [], xxs: [], 58 | }, 59 | elements: [], 60 | saveLayouts: (layouts: any): any => console.log('Save layout', layouts) 61 | }; 62 | 63 | public render(): JSX.Element { 64 | const { layouts, elements, saveLayouts } = this.props; 65 | return ; 66 | } 67 | } 68 | 69 | // Home.propTypes = { 70 | // layouts: PropTypes.object, 71 | // elements: PropTypes.array, 72 | // 73 | // saveLayouts: PropTypes.func 74 | // }; 75 | 76 | // Home.defaultProps = { 77 | // layouts: { 78 | // lg: [], md: [], sm: [], xs: [], xxs: [], 79 | // }, 80 | // elements: [], 81 | // saveLayouts: () => console.log('Save layout') 82 | // }; 83 | 84 | 85 | export default connect(mapStateToProps, mapDispatchToProps)(Home); 86 | -------------------------------------------------------------------------------- /src/views/Intro.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FormattedMessage } from 'react-intl'; 3 | 4 | const Home = () => ( 5 | 6 | ); 7 | 8 | export default Home; 9 | -------------------------------------------------------------------------------- /src/views/index.js: -------------------------------------------------------------------------------- 1 | export { default as Home } from './Home'; 2 | export { default as Configuration } from './Configuration'; 3 | 4 | export { default as Intro } from './Intro'; 5 | export { default as About } from './About'; 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "target": "es5", 5 | "sourceMap": true, 6 | "lib": [ 7 | "dom", 8 | "dom.iterable", 9 | "esnext" 10 | ], 11 | "allowJs": true, 12 | "skipLibCheck": true, 13 | "esModuleInterop": true, 14 | "allowSyntheticDefaultImports": true, 15 | "strict": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "jsx": "react", 22 | // "noEmit": true, 23 | 24 | "noImplicitAny": true, 25 | "noImplicitThis": true, 26 | "strictNullChecks": true 27 | 28 | }, 29 | "include": [ 30 | "src" 31 | ] 32 | } 33 | --------------------------------------------------------------------------------