Initial commit
96
.gitlab-ci.yml
Normal file
@ -0,0 +1,96 @@
|
||||
# IMPORTANT:
|
||||
#
|
||||
# This CI/CD will run on an Ubuntu VM. After this script runs, the VM will retain the state.
|
||||
# It's your responsibility to clean the VM up in the cleanup stage after job finishes executing.
|
||||
# This script runs on Microk8s. since our deployments are on Kubernetes, our aim is to create EXACT same replica for test, staging and production.
|
||||
|
||||
#Define stages
|
||||
stages:
|
||||
- build_n_test
|
||||
- e2e_test
|
||||
- deploy_staging
|
||||
- deploy_production
|
||||
|
||||
build_n_test:
|
||||
stage: build_n_test
|
||||
script:
|
||||
- sudo docker stop $(sudo docker ps -aq) || echo 'No docker containers'
|
||||
- sudo docker rm $(sudo docker ps -aq) || echo 'No docker containers'
|
||||
- sudo docker run --name mongo -p 27017:27017 -d mongo:3.4
|
||||
- cd backend
|
||||
- sudo docker build -t fyipe-project/backend:1.0.$CI_PIPELINE_IID .
|
||||
- sudo docker run --name fyipe --network container:mongo fyipe-project/backend:1.0.$CI_PIPELINE_IID npm test
|
||||
- cd ..
|
||||
|
||||
e2e_test:
|
||||
stage: e2e_test
|
||||
script:
|
||||
- cd kubernetes
|
||||
- chmod +x ./ci/setup-machine.sh
|
||||
- ./ci/setup-machine.sh
|
||||
- chmod +x ./ci/setup.sh
|
||||
- ./ci/setup.sh
|
||||
- BACKEND_CONTAINER_NAME=`sudo kubectl get pods -l app=backend -o custom-columns=:metadata.name`
|
||||
- sudo kubectl get pod BACKEND_CONTAINER_NAME=
|
||||
only:
|
||||
refs:
|
||||
- release
|
||||
- master
|
||||
|
||||
deploy_staging:
|
||||
stage: deploy_staging
|
||||
script:
|
||||
- cd kubernetes
|
||||
- chmod +x ./ci/deployment-setup.sh
|
||||
- ./ci/deployment-setup.sh
|
||||
- chmod +x ./ci/deployment-staging-setup.sh
|
||||
- ./ci/deployment-staging-setup.sh
|
||||
- cd ..
|
||||
- git clone https://$GIT_USERNAME:$GIT_PASSWORD@gitlab.com/fyipe-project/backend.git
|
||||
- cd backend
|
||||
- git checkout master
|
||||
- sudo docker build -t fyipe-project/backend:master .
|
||||
- sudo docker tag fyipe-project/backend:master registry.gitlab.com/fyipe-project/backend:2.0.$CI_PIPELINE_IID
|
||||
- sudo docker tag fyipe-project/backend:master registry.gitlab.com/fyipe-project/backend:master
|
||||
- sudo docker push registry.gitlab.com/fyipe-project/backend:2.0.$CI_PIPELINE_IID
|
||||
- sudo docker push registry.gitlab.com/fyipe-project/backend:master
|
||||
- sudo $HOME/google-cloud-sdk/bin/kubectl set image deployment/backend backend=registry.gitlab.com/fyipe-project/backend:2.0.$CI_PIPELINE_IID
|
||||
- cd ..
|
||||
- cd kubernetes
|
||||
- chmod +x ./ci/deployment-cleanup.sh
|
||||
- ./ci/deployment-cleanup.sh
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
environment:
|
||||
name: staging
|
||||
|
||||
deploy_production:
|
||||
stage: deploy_production
|
||||
script:
|
||||
- sudo rm -r *
|
||||
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/fyipe-project/kubernetes
|
||||
- cd kubernetes
|
||||
- chmod +x ./ci/deployment-setup.sh
|
||||
- ./ci/deployment-setup.sh
|
||||
- chmod +x ./ci/deployment-production-setup.sh
|
||||
- ./ci/deployment-production-setup.sh
|
||||
- cd ..
|
||||
- git clone https://$GIT_USERNAME:$GIT_PASSWORD@gitlab.com/fyipe-project/backend.git
|
||||
- cd backend
|
||||
- git checkout release
|
||||
- sudo docker build -t fyipe-project/backend:latest .
|
||||
- sudo docker tag fyipe-project/backend:latest registry.gitlab.com/fyipe-project/backend:1.0.$CI_PIPELINE_IID
|
||||
- sudo docker tag fyipe-project/backend:latest registry.gitlab.com/fyipe-project/backend:latest
|
||||
- sudo docker push registry.gitlab.com/fyipe-project/backend:1.0.$CI_PIPELINE_IID
|
||||
- sudo docker push registry.gitlab.com/fyipe-project/backend:latest
|
||||
- sudo $HOME/google-cloud-sdk/bin/kubectl set image deployment/backend backend=registry.gitlab.com/fyipe-project/backend:1.0.$CI_PIPELINE_IID
|
||||
- cd ..
|
||||
- cd kubernetes
|
||||
- chmod +x ./ci/deployment-cleanup.sh
|
||||
- ./ci/deployment-cleanup.sh
|
||||
only:
|
||||
refs:
|
||||
- release
|
||||
environment:
|
||||
name: production
|
3
accounts/.babelrc
Executable file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["loadable-components/babel"]
|
||||
}
|
2
accounts/.dockerignore
Executable file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
build
|
4
accounts/.eslintignore
Executable file
@ -0,0 +1,4 @@
|
||||
/node_modules
|
||||
/build
|
||||
/coverage
|
||||
*.test.js
|
77
accounts/.eslintrc.json
Executable file
@ -0,0 +1,77 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 8,
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true,
|
||||
"jsx": true,
|
||||
"spread": true
|
||||
},
|
||||
"sourceType": "module"
|
||||
},
|
||||
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"jquery": true,
|
||||
"es6": true
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
"extends": ["eslint:recommended", "plugin:react/recommended"],
|
||||
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"rules": {
|
||||
"no-fallthrough": "error",
|
||||
"no-unreachable": "error",
|
||||
"no-cond-assign": "error",
|
||||
"no-console": "error",
|
||||
"valid-typeof": "error",
|
||||
"no-func-assign": "error",
|
||||
"no-extra-semi": "error",
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"varsIgnorePattern": "[iI]gnored",
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true,
|
||||
"argsIgnorePattern": "[iI]gnored"
|
||||
}
|
||||
],
|
||||
"no-undef": "error",
|
||||
"no-empty": "error",
|
||||
"no-case-declarations": "error",
|
||||
"no-mixed-spaces-and-tabs": "error",
|
||||
"no-useless-escape": "error",
|
||||
"react/jsx-no-undef": "error",
|
||||
"quotes": ["error", "single"],
|
||||
"react/jsx-no-bind": ["error", {
|
||||
"allowArrowFunctions": true,
|
||||
"allowBind": false,
|
||||
"ignoreRefs": false
|
||||
}],
|
||||
"react/no-children-prop": "error",
|
||||
"react/no-deprecated": "error",
|
||||
"react/no-array-index-key": "off",
|
||||
"react/boolean-prop-naming": "error",
|
||||
"react/no-is-mounted": "error",
|
||||
"react/no-find-dom-node": "error",
|
||||
"react/no-did-update-set-state": "error",
|
||||
"react/no-unknown-property": "error",
|
||||
"react/no-unused-prop-types": "error",
|
||||
"react/jsx-no-duplicate-props": "error",
|
||||
"react/no-unused-state": "error",
|
||||
"react/jsx-uses-vars": "error",
|
||||
"react/prop-types": "error",
|
||||
"react/react-in-jsx-scope": "error",
|
||||
"react/no-string-refs": "warn",
|
||||
"jsx-a11y/href-no-hash": [0],
|
||||
"react/no-unescaped-entities": "error",
|
||||
"react/display-name": ["error", {
|
||||
"ignoreTranspilerName": true
|
||||
}]
|
||||
}
|
||||
}
|
26
accounts/.gitignore
vendored
Executable file
@ -0,0 +1,26 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
.vscode/
|
||||
.idea
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
yarn.lock
|
||||
Untitled-1
|
99
accounts/.gitlab-ci.yml
Executable file
@ -0,0 +1,99 @@
|
||||
# IMPORTANT:
|
||||
#
|
||||
# This CI/CD will run on an Ubuntu VM. After this script runs, the VM will retain the state.
|
||||
# It's your responsibility to clean the VM up in the cleanup stage after job finishes executing.
|
||||
# This script runs on Minikube. since our deployments are on Kubernetes, our aim is to create EXACT same replica for test, staging and production.
|
||||
|
||||
#Define statges
|
||||
stages:
|
||||
- setup_environment
|
||||
- build_n_test
|
||||
- deploy_staging
|
||||
- deploy_production
|
||||
- cleanup
|
||||
- deployment_cleanup
|
||||
|
||||
before_script:
|
||||
- sudo rm -r *
|
||||
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/fyipe-project/kubernetes
|
||||
- cd kubernetes
|
||||
|
||||
#Set up the environment
|
||||
setup_environment:
|
||||
stage: setup_environment
|
||||
script:
|
||||
- chmod +x ./ci/setup-machine.sh
|
||||
- ./ci/setup-machine.sh
|
||||
|
||||
build_n_test:
|
||||
stage: build_n_test
|
||||
script:
|
||||
- chmod +x ./ci/setup.sh
|
||||
- ./ci/setup.sh
|
||||
- ACCOUNTS_CONTAINER=`sudo kubectl get pods -l app=accounts -o custom-columns=:metadata.name`
|
||||
- sudo kubectl exec $ACCOUNTS_CONTAINER -- npm test
|
||||
|
||||
deploy_staging:
|
||||
stage: deploy_staging
|
||||
script:
|
||||
- chmod +x ./ci/deployment-setup.sh
|
||||
- ./ci/deployment-setup.sh
|
||||
- chmod +x ./ci/deployment-staging-setup.sh
|
||||
- ./ci/deployment-staging-setup.sh
|
||||
- cd ..
|
||||
- git clone https://$GIT_USERNAME:$GIT_PASSWORD@gitlab.com/fyipe-project/accounts.git
|
||||
- cd accounts
|
||||
- git checkout master
|
||||
- sudo docker build -t fyipe-project/accounts:master .
|
||||
- sudo docker tag fyipe-project/accounts:master registry.gitlab.com/fyipe-project/accounts:2.0.$CI_PIPELINE_IID
|
||||
- sudo docker tag fyipe-project/accounts:master registry.gitlab.com/fyipe-project/accounts:master
|
||||
- sudo docker push registry.gitlab.com/fyipe-project/accounts:2.0.$CI_PIPELINE_IID
|
||||
- sudo docker push registry.gitlab.com/fyipe-project/accounts:master
|
||||
- sudo $HOME/google-cloud-sdk/bin/kubectl set image deployment/accounts accounts=registry.gitlab.com/fyipe-project/accounts:2.0.$CI_PIPELINE_IID
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
environment:
|
||||
name: staging
|
||||
|
||||
|
||||
deploy_production:
|
||||
stage: deploy_production
|
||||
script:
|
||||
- chmod +x ./ci/deployment-setup.sh
|
||||
- ./ci/deployment-setup.sh
|
||||
- chmod +x ./ci/deployment-production-setup.sh
|
||||
- ./ci/deployment-production-setup.sh
|
||||
- cd ..
|
||||
- git clone https://$GIT_USERNAME:$GIT_PASSWORD@gitlab.com/fyipe-project/accounts.git
|
||||
- cd accounts
|
||||
- git checkout release
|
||||
- sudo docker build -t fyipe-project/accounts:latest .
|
||||
- sudo docker tag fyipe-project/accounts:latest registry.gitlab.com/fyipe-project/accounts:1.0.$CI_PIPELINE_IID
|
||||
- sudo docker tag fyipe-project/accounts:latest registry.gitlab.com/fyipe-project/accounts:latest
|
||||
- sudo docker push registry.gitlab.com/fyipe-project/accounts:1.0.$CI_PIPELINE_IID
|
||||
- sudo docker push registry.gitlab.com/fyipe-project/accounts:latest
|
||||
- sudo $HOME/google-cloud-sdk/bin/kubectl set image deployment/accounts accounts=registry.gitlab.com/fyipe-project/accounts:1.0.$CI_PIPELINE_IID
|
||||
only:
|
||||
refs:
|
||||
- release
|
||||
environment:
|
||||
name: production
|
||||
|
||||
cleanup_job:
|
||||
stage: cleanup
|
||||
script:
|
||||
- chmod +x ./ci/cleanup.sh
|
||||
- ./ci/cleanup.sh
|
||||
when: always
|
||||
|
||||
deployment_cleanup:
|
||||
stage: deployment_cleanup
|
||||
script:
|
||||
- chmod +x ./ci/deployment-cleanup.sh
|
||||
- ./ci/deployment-cleanup.sh
|
||||
only:
|
||||
refs:
|
||||
- release
|
||||
- master
|
||||
when: always
|
30
accounts/Dockerfile
Executable file
@ -0,0 +1,30 @@
|
||||
#
|
||||
# Accounts Dockerfile
|
||||
#
|
||||
|
||||
# Pull base image nodejs image.
|
||||
FROM node:10
|
||||
|
||||
#SET ENV Variables
|
||||
ENV PRODUCTION=true
|
||||
|
||||
RUN mkdir -p /usr/src/app
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install app dependencies
|
||||
COPY package*.json /usr/src/app/
|
||||
RUN npm install
|
||||
|
||||
# Copy app source
|
||||
COPY . /usr/src/app
|
||||
|
||||
# Bundle app source
|
||||
RUN npm run build
|
||||
|
||||
# Expose ports.
|
||||
# - 3003: accounts
|
||||
EXPOSE 3003
|
||||
|
||||
#Run the app
|
||||
CMD [ "npm", "start" ]
|
38
accounts/README.md
Executable file
@ -0,0 +1,38 @@
|
||||
# Fyipe Dashboard - Accounts
|
||||
|
||||
Repository for user authentication of the fyipe dashboard
|
||||
|
||||
## Stack
|
||||
|
||||
- Reactjs - UI Library
|
||||
- Redux - State managment
|
||||
- Redux Forms - Forms
|
||||
|
||||
|
||||
## Start
|
||||
|
||||
To run the app:
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
In development:
|
||||
|
||||
```
|
||||
npm run dev
|
||||
```
|
||||
|
||||
In production:
|
||||
|
||||
```
|
||||
npm start
|
||||
```
|
||||
|
||||
## Puppeteer Tests
|
||||
|
||||
To run puppeteer tests for this repo, follow these steps:
|
||||
|
||||
- Start the backend server
|
||||
- Start the accounts application
|
||||
- Then run ```npm run jest``` from your terminal
|
11
accounts/index.js
Executable file
@ -0,0 +1,11 @@
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
const app = express();
|
||||
|
||||
app.use(express.static(path.join(__dirname, 'build')));
|
||||
|
||||
app.get('/*', function(req, res) {
|
||||
res.sendFile(path.join(__dirname, 'build', 'index.html'));
|
||||
});
|
||||
|
||||
app.listen(3003);
|
16032
accounts/package-lock.json
generated
Executable file
114
accounts/package.json
Executable file
@ -0,0 +1,114 @@
|
||||
{
|
||||
"name": "fyipe-accounts",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@trendmicro/react-dropdown": "^1.3.0",
|
||||
"axios": "^0.18.0",
|
||||
"browserslist": "^4.6.1",
|
||||
"card-validator": "^4.3.0",
|
||||
"chart.js": "^2.7.2",
|
||||
"clipboard": "^2.0.1",
|
||||
"cloudboost": "^6.6.6",
|
||||
"components": "^0.1.0",
|
||||
"connected-react-router": "^4.5.0",
|
||||
"creditcard-generator": "0.0.7",
|
||||
"express": "^4.16.4",
|
||||
"faker": "^4.1.0",
|
||||
"file-saver": "^2.0.1",
|
||||
"fuzzy-match-utils": "^1.3.0",
|
||||
"history": "^4.7.2",
|
||||
"humanize-duration": "^3.15.3",
|
||||
"jest": "^24.7.1",
|
||||
"js-uuid": "0.0.6",
|
||||
"jshint": "^2.9.6",
|
||||
"loadable": "^1.0.0",
|
||||
"loadable-components": "^2.2.3",
|
||||
"loaders.css": "^0.1.2",
|
||||
"lodash": "^4.17.5",
|
||||
"material-ui": "^0.20.0",
|
||||
"mixpanel-browser": "^2.22.3",
|
||||
"mockdate": "^2.0.2",
|
||||
"moment": "^2.22.2",
|
||||
"moment-range": "^4.0.1",
|
||||
"prop-types": "^15.6.1",
|
||||
"puppeteer": "^1.17.0",
|
||||
"query-string": "^5.1.1",
|
||||
"react": "^16.5.2",
|
||||
"react-click-outside": "github:tj/react-click-outside",
|
||||
"react-daterange-picker": "^2.0.1",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-frontload": "^1.0.3",
|
||||
"react-ga": "^2.5.3",
|
||||
"react-hover-observer": "^2.1.0",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-loaders": "^3.0.1",
|
||||
"react-mixpanel": "0.0.11",
|
||||
"react-moment-proptypes": "^1.6.0",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-router-redux": "^4.0.8",
|
||||
"react-scripts": "^3.0.1",
|
||||
"react-select-fyipe": "^2.1.8",
|
||||
"react-stripe-elements": "^1.6.0",
|
||||
"react-widgets": "^4.4.9",
|
||||
"react-with-direction": "^1.3.0",
|
||||
"recharts": "^1.3.0",
|
||||
"redux": "^3.7.2",
|
||||
"redux-axios-middleware": "^4.0.0",
|
||||
"redux-form": "^7.3.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"sane-email-validation": "^1.1.0",
|
||||
"should": "^13.2.3",
|
||||
"to-pascal-case": "^1.0.0",
|
||||
"universal-cookie": "^4.0.0",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"dev": "export PORT=3003 && react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "npm run lint",
|
||||
"jest": "jest src/test/index.test.js",
|
||||
"start": "node index.js",
|
||||
"audit": "npm-audit-ci-wrapper --threshold=high"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios-mock-adapter": "^1.15.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-loader": "8.0.5",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"eslint": "5.16.0",
|
||||
"jest-localstorage-mock": "^2.2.0",
|
||||
"npm-audit-ci-wrapper": "^2.2.1",
|
||||
"react-test-renderer": "^16.5.2",
|
||||
"redux-logger": "^3.0.6",
|
||||
"redux-mock-store": "^1.5.3",
|
||||
"webpack": "^4.29.6"
|
||||
},
|
||||
"jest": {
|
||||
"collectCoverageFrom": [
|
||||
"src/**/*.js",
|
||||
"!src/**/*.stories.js",
|
||||
"!src/store.js",
|
||||
"!src/config.js",
|
||||
"!src/routes.js",
|
||||
"!src/setupTests.js"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
10
accounts/public/assets/css/Selector.css
Executable file
@ -0,0 +1,10 @@
|
||||
#login .selector {
|
||||
font-size: 18px;
|
||||
padding: 10px 12px;
|
||||
width: 100%;
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.18);
|
||||
border: 1px solid #ddd;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
height: 45px;
|
||||
}
|
201
accounts/public/assets/css/blockchart.css
Executable file
@ -0,0 +1,201 @@
|
||||
/******* Row containing Bar Chart *******/
|
||||
|
||||
/******* Simple Bar Chart *******/
|
||||
div.block-chart-main{
|
||||
position: relative;
|
||||
height: 75px;
|
||||
margin-top:-15px;
|
||||
margin-left:10px;
|
||||
}
|
||||
.db-Trend-colInformation{
|
||||
margin-right: 8px;
|
||||
}
|
||||
div.block-chart {
|
||||
position: relative;
|
||||
height: 75px;
|
||||
float: right;
|
||||
overflow: hidden;
|
||||
width: 101%; /* IE overflow fix */
|
||||
}
|
||||
|
||||
div.block-chart div.bar {
|
||||
float: left;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 6px;
|
||||
cursor: pointer;
|
||||
/* Border instead of margin so we get the hover behavior we want */
|
||||
border-left: 1px solid #fff;
|
||||
border-right: 1px solid #fff;
|
||||
/* DEFAULT IS GREEN */
|
||||
background: rgb(0, 128, 168);
|
||||
}
|
||||
|
||||
div.block-chart div.bar:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
div.block-chart div.bar.empty {
|
||||
float: left;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 6px;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
/* Border instead of margin so we get the hover behavior we want */
|
||||
border-left: 1px solid #fff;
|
||||
border-right: 1px solid #fff;
|
||||
|
||||
opacity: 0.6;
|
||||
|
||||
/* DEFAULT IS GREEN */
|
||||
background: rgb(0, 128, 168);
|
||||
}
|
||||
|
||||
div.block-chart div.bar.empty:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
div.block-chart div.bar.mid {
|
||||
background: #FFDE24;
|
||||
}
|
||||
|
||||
div.block-chart div.bar.down {
|
||||
background: #FA6D46;
|
||||
}
|
||||
|
||||
div.block-chart div.bar:first-child {
|
||||
border-left: 0;
|
||||
}
|
||||
div.block-chart div.bar:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
******* Tipsy Tooltips ******/
|
||||
|
||||
.tipsy {
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
padding: 5px;
|
||||
z-index: 100000;
|
||||
}
|
||||
.tipsy-inner {
|
||||
background-color: #32325d;
|
||||
color: #FFF;
|
||||
max-width: 200px;
|
||||
padding: 5px 12px 5px 12px;
|
||||
line-height: 19px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Rounded corners */
|
||||
.tipsy-inner {
|
||||
border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
/* Uncomment for shadow */
|
||||
/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/
|
||||
|
||||
.tipsy-arrow {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
line-height: 0;
|
||||
border: 5px dashed #32325d;
|
||||
}
|
||||
|
||||
/* Rules to colour arrows */
|
||||
.tipsy-arrow-n {
|
||||
border-bottom-color: #32325d;
|
||||
}
|
||||
.tipsy-arrow-s {
|
||||
border-top-color: #32325d;
|
||||
}
|
||||
.tipsy-arrow-e {
|
||||
border-left-color: #32325d;
|
||||
}
|
||||
.tipsy-arrow-w {
|
||||
border-right-color: #32325d;
|
||||
}
|
||||
|
||||
.tipsy-n .tipsy-arrow {
|
||||
top: 0px;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border-bottom-style: solid;
|
||||
border-top: none;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.tipsy-nw .tipsy-arrow {
|
||||
top: 0;
|
||||
left: 10px;
|
||||
border-bottom-style: solid;
|
||||
border-top: none;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.tipsy-ne .tipsy-arrow {
|
||||
top: 0; right: 10px;
|
||||
border-bottom-style: solid;
|
||||
border-top: none;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.tipsy-s .tipsy-arrow {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border-top-style: solid;
|
||||
border-bottom: none;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.tipsy-sw .tipsy-arrow {
|
||||
bottom: 0; left: 10px;
|
||||
border-top-style: solid;
|
||||
border-bottom: none;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.tipsy-se .tipsy-arrow {
|
||||
bottom: 0;
|
||||
right: 10px;
|
||||
border-top-style: solid;
|
||||
border-bottom: none;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.tipsy-e .tipsy-arrow {
|
||||
right: 0;
|
||||
top: 50%;
|
||||
margin-top: -5px;
|
||||
border-left-style: solid;
|
||||
border-right: none;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
.tipsy-w .tipsy-arrow {
|
||||
left: 0;
|
||||
top: 50%;
|
||||
margin-top: -5px;
|
||||
border-right-style: solid;
|
||||
border-left: none;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1180px) {
|
||||
div.block-chart div.bar {
|
||||
width: 5px;
|
||||
}
|
||||
div.block-chart div.bar.empty {
|
||||
width: 5px;
|
||||
}
|
||||
.chart-font{
|
||||
font-size: 90%;
|
||||
}
|
||||
}
|
51011
accounts/public/assets/css/dashboard.css
Executable file
1779
accounts/public/assets/css/loader.css
Executable file
10528
accounts/public/assets/css/newdashboard.css
Executable file
9721
accounts/public/assets/css/newdashobard2.css
Executable file
974
accounts/public/assets/css/reactwidgets.css
Executable file
@ -0,0 +1,974 @@
|
||||
.rw-btn,
|
||||
.rw-input-reset,
|
||||
.rw-input,
|
||||
.rw-dropdown-list-autofill,
|
||||
.rw-filter-input {
|
||||
color: inherit;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
background: none;
|
||||
background-image: none;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation
|
||||
}
|
||||
|
||||
.rw-btn::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0
|
||||
}
|
||||
|
||||
select.rw-input {
|
||||
text-transform: none
|
||||
}
|
||||
|
||||
html input[type="button"].rw-input {
|
||||
-webkit-appearance: button;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
textarea.rw-input {
|
||||
overflow: auto;
|
||||
resize: vertical
|
||||
}
|
||||
|
||||
button[disabled].rw-input,
|
||||
fieldset[disabled] .rw-input,
|
||||
html input[disabled].rw-input {
|
||||
cursor: not-allowed
|
||||
}
|
||||
|
||||
button.rw-input::-moz-focus-inner,
|
||||
input.rw-input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'RwWidgets';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
src: url('../fonts/rw-widgets.eot?v=4.1.0');
|
||||
src: url('../fonts/rw-widgets.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/rw-widgets.woff?v=4.1.0') format('woff'), url('../fonts/rw-widgets.ttf?v=4.1.0') format('truetype'), url('../fonts/rw-widgets.svg?v=4.1.0#fontawesomeregular') format('svg')
|
||||
}
|
||||
|
||||
.rw-i {
|
||||
display: inline-block;
|
||||
color: inherit;
|
||||
font-family: RwWidgets;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased
|
||||
}
|
||||
|
||||
.rw-i-caret-down:before {
|
||||
content: '\e803'
|
||||
}
|
||||
|
||||
.rw-i-caret-up:before {
|
||||
content: '\e800'
|
||||
}
|
||||
|
||||
.rw-i-chevron-left:before {
|
||||
content: '\f104'
|
||||
}
|
||||
|
||||
.rw-i-chevron-right:before {
|
||||
content: '\f105'
|
||||
}
|
||||
|
||||
.rw-i-clock-o:before {
|
||||
content: '\e805'
|
||||
}
|
||||
|
||||
.rw-i-calendar:before {
|
||||
content: '\e804'
|
||||
}
|
||||
|
||||
.rw-i-search:before {
|
||||
content: '\e801'
|
||||
}
|
||||
|
||||
.rw-btn {
|
||||
position: relative;
|
||||
color: #333;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
outline: none
|
||||
}
|
||||
|
||||
.rw-state-readonly .rw-btn,
|
||||
.rw-state-disabled .rw-btn {
|
||||
cursor: not-allowed
|
||||
}
|
||||
|
||||
.rw-btn-select {
|
||||
opacity: .75;
|
||||
filter: alpha(opacity=75);
|
||||
transition: opacity 150ms ease-in
|
||||
}
|
||||
|
||||
.rw-btn-select:hover,
|
||||
.rw-state-focus .rw-btn-select,
|
||||
:hover>.rw-btn-select {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100)
|
||||
}
|
||||
|
||||
.rw-btn-primary {
|
||||
width: 100%;
|
||||
white-space: normal;
|
||||
line-height: 2em
|
||||
}
|
||||
|
||||
.rw-btn-primary:hover {
|
||||
background-color: #e6e6e6
|
||||
}
|
||||
|
||||
.rw-btn-select[disabled],
|
||||
.rw-btn-primary[disabled],
|
||||
fieldset[disabled] .rw-btn-select,
|
||||
fieldset[disabled] .rw-btn-primary {
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
opacity: .65;
|
||||
filter: alpha(opacity=65);
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.rw-sr {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0
|
||||
}
|
||||
|
||||
.rw-widget {
|
||||
background-clip: border-box;
|
||||
border: none;
|
||||
color: #333;
|
||||
font-size: 1em;
|
||||
font-family: inherit;
|
||||
outline: none;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.rw-widget,
|
||||
.rw-widget * {
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.rw-widget:before,
|
||||
.rw-widget *:before,
|
||||
.rw-widget:after,
|
||||
.rw-widget *:after {
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.rw-widget>.rw-widget-container {
|
||||
width: 100%;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.rw-widget-container {
|
||||
background-color: #fff;
|
||||
border: #ccc 1px solid;
|
||||
border-radius: 4px
|
||||
}
|
||||
|
||||
.rw-widget-container.rw-state-focus,
|
||||
.rw-state-focus>.rw-widget-container,
|
||||
.rw-widget-container.rw-state-focus:hover,
|
||||
.rw-state-focus>.rw-widget-container:hover {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 8px rgba(102, 175, 233, 0.6)
|
||||
}
|
||||
|
||||
.rw-widget-container.rw-state-readonly,
|
||||
.rw-state-readonly>.rw-widget-container {
|
||||
cursor: not-allowed
|
||||
}
|
||||
|
||||
.rw-widget-container.rw-state-disabled,
|
||||
.rw-state-disabled>.rw-widget-container,
|
||||
fieldset[disabled] .rw-widget-container,
|
||||
.rw-widget-container.rw-state-disabled:hover,
|
||||
.rw-state-disabled>.rw-widget-container:hover,
|
||||
fieldset[disabled] .rw-widget-container:hover,
|
||||
.rw-widget-container.rw-state-disabled:active,
|
||||
.rw-state-disabled>.rw-widget-container:active,
|
||||
fieldset[disabled] .rw-widget-container:active {
|
||||
box-shadow: none;
|
||||
cursor: not-allowed
|
||||
}
|
||||
|
||||
.rw-widget-picker {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-collapse: separate;
|
||||
display: inline-table;
|
||||
height: 2.429em
|
||||
}
|
||||
|
||||
.rw-widget-picker>* {
|
||||
position: relative;
|
||||
border: none;
|
||||
outline: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: table-cell
|
||||
}
|
||||
|
||||
.rw-widget-picker>.rw-select {
|
||||
width: 1%;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.rw-open>.rw-widget-picker {
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0
|
||||
}
|
||||
|
||||
.rw-open-up>.rw-widget-picker {
|
||||
border-top-right-radius: 0;
|
||||
border-top-left-radius: 0
|
||||
}
|
||||
|
||||
fieldset[disabled] .rw-widget-picker,
|
||||
.rw-state-disabled>.rw-widget-picker {
|
||||
background-color: #eee
|
||||
}
|
||||
|
||||
.rw-select {
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.rw-select>* {
|
||||
width: 1.9em;
|
||||
height: 100%
|
||||
}
|
||||
|
||||
.rw-state-readonly .rw-select,
|
||||
.rw-state-disabled .rw-select {
|
||||
cursor: not-allowed
|
||||
}
|
||||
|
||||
.rw-select-bordered {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-left: #ccc 1px solid
|
||||
}
|
||||
|
||||
.rw-select-bordered:hover,
|
||||
.rw-select-bordered:active {
|
||||
background-color: #e6e6e6
|
||||
}
|
||||
|
||||
.rw-select-bordered:active {
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125)
|
||||
}
|
||||
|
||||
.rw-state-disabled .rw-select-bordered,
|
||||
.rw-state-readonly .rw-select-bordered,
|
||||
fieldset[disabled] .rw-select-bordered,
|
||||
.rw-state-disabled .rw-select-bordered:hover,
|
||||
.rw-state-readonly .rw-select-bordered:hover,
|
||||
fieldset[disabled] .rw-select-bordered:hover,
|
||||
.rw-state-disabled .rw-select-bordered:active,
|
||||
.rw-state-readonly .rw-select-bordered:active,
|
||||
fieldset[disabled] .rw-select-bordered:active {
|
||||
cursor: not-allowed;
|
||||
background-color: inherit;
|
||||
background-image: none;
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.rw-rtl .rw-select-bordered {
|
||||
border-right: #ccc 1px solid;
|
||||
border-left: none
|
||||
}
|
||||
|
||||
.rw-rtl {
|
||||
direction: rtl
|
||||
}
|
||||
|
||||
.rw-input-reset,
|
||||
.rw-input,
|
||||
.rw-dropdown-list-autofill,
|
||||
.rw-filter-input {
|
||||
outline: 0
|
||||
}
|
||||
|
||||
.rw-input-reset::-moz-placeholder {
|
||||
color: #999;
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.rw-input-reset:-ms-input-placeholder {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.rw-input-reset::-webkit-input-placeholder {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.rw-input,
|
||||
.rw-dropdown-list-autofill,
|
||||
.rw-filter-input {
|
||||
color: #555;
|
||||
padding: 0 .857em;
|
||||
background-color: #fff
|
||||
}
|
||||
|
||||
.rw-input[type='text']::-ms-clear {
|
||||
display: none
|
||||
}
|
||||
|
||||
.rw-input[disabled],
|
||||
fieldset[disabled] .rw-input {
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
opacity: 1;
|
||||
background-color: #eee;
|
||||
border-color: #ccc
|
||||
}
|
||||
|
||||
.rw-input[readonly] {
|
||||
cursor: not-allowed
|
||||
}
|
||||
|
||||
.rw-i.rw-loading {
|
||||
display: block;
|
||||
background: url('../img/loading.gif') no-repeat center;
|
||||
min-width: 16px;
|
||||
width: 1.9em;
|
||||
height: 16px
|
||||
}
|
||||
|
||||
.rw-i.rw-loading:before {
|
||||
content: ''
|
||||
}
|
||||
|
||||
.rw-placeholder {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.rw-detect-autofill:-webkit-autofill {
|
||||
animation-name: react-widgets-autofill-start;
|
||||
transition: background-color 50000s ease-in-out 0s
|
||||
}
|
||||
|
||||
.rw-detect-autofill:not(:-webkit-autofill) {
|
||||
animation-name: react-widgets-autofill-cancel
|
||||
}
|
||||
|
||||
.rw-webkit-autofill .rw-widget-container,
|
||||
.rw-input:-webkit-autofill {
|
||||
background-color: #faffbd !important;
|
||||
background-image: none !important;
|
||||
color: #000 !important
|
||||
}
|
||||
|
||||
.rw-widget-input,
|
||||
.rw-filter-input {
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075)
|
||||
}
|
||||
|
||||
.rw-widget-input.rw-state-focus {
|
||||
box-shadow: 0 0 8px rgba(102, 175, 233, 0.6), inset 0 1px 1px rgba(0, 0, 0, 0.075)
|
||||
}
|
||||
|
||||
.rw-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
font-size: 1em;
|
||||
outline: 0;
|
||||
overflow: auto;
|
||||
max-height: 200px
|
||||
}
|
||||
|
||||
.rw-list-option {
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent
|
||||
}
|
||||
|
||||
.rw-list-option.rw-state-focus,
|
||||
.rw-list-option.rw-state-focus:hover {
|
||||
background-color: transparent;
|
||||
color: #333
|
||||
}
|
||||
|
||||
.rw-list-option:hover,
|
||||
.rw-list-option:hover.rw-state-focus {
|
||||
background-color: #e6e6e6;
|
||||
border-color: #e6e6e6;
|
||||
color: #333
|
||||
}
|
||||
|
||||
.rw-list-option.rw-state-selected,
|
||||
.rw-list-option.rw-state-selected:hover {
|
||||
background-color: #337ab7;
|
||||
border-color: #337ab7;
|
||||
color: white
|
||||
}
|
||||
|
||||
fieldset[disabled] .rw-list-option,
|
||||
.rw-list-option.rw-state-disabled,
|
||||
.rw-list-option.rw-state-readonly {
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
color: #999;
|
||||
filter: alpha(opacity=7);
|
||||
opacity: .7
|
||||
}
|
||||
|
||||
fieldset[disabled] .rw-list-option:hover,
|
||||
.rw-list-option.rw-state-disabled:hover,
|
||||
.rw-list-option.rw-state-readonly:hover {
|
||||
background: none;
|
||||
border-color: transparent
|
||||
}
|
||||
|
||||
.rw-list-empty,
|
||||
.rw-list-option,
|
||||
.rw-list-optgroup {
|
||||
padding: .143em .75em;
|
||||
outline: 0
|
||||
}
|
||||
|
||||
.rw-list-optgroup {
|
||||
font-weight: bold;
|
||||
padding-top: 7px
|
||||
}
|
||||
|
||||
.rw-list-option-create {
|
||||
border-top: 1px #ccc solid
|
||||
}
|
||||
|
||||
.rw-dropdown-list-autofill {
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.rw-dropdown-list-input {
|
||||
background-color: transparent;
|
||||
vertical-align: middle;
|
||||
padding-right: 0;
|
||||
max-width: 1px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.rw-rtl .rw-dropdown-list-input {
|
||||
padding-right: .857em;
|
||||
padding-left: 0
|
||||
}
|
||||
|
||||
.rw-filter-input {
|
||||
position: relative;
|
||||
margin: 4px;
|
||||
padding-right: 0
|
||||
}
|
||||
|
||||
.rw-filter-input .rw-rtl {
|
||||
padding-right: .857em;
|
||||
padding-left: 0
|
||||
}
|
||||
|
||||
.rw-filter-input .rw-select,
|
||||
.rw-filter-input .rw-btn {
|
||||
opacity: .75;
|
||||
filter: alpha(opacity=75);
|
||||
cursor: text
|
||||
}
|
||||
|
||||
.rw-filter-input>.rw-select,
|
||||
.rw-filter-input>.rw-select:active,
|
||||
.rw-filter-input>.rw-select:hover {
|
||||
background: none;
|
||||
cursor: initial;
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.rw-number-picker .rw-btn {
|
||||
cursor: pointer;
|
||||
height: calc(1.2145em - 1px);
|
||||
margin-top: -1px\9;
|
||||
height: 1.2145em\9;
|
||||
line-height: 1.2145em;
|
||||
line-height: calc(1.2145em - 1px);
|
||||
display: block;
|
||||
border: none
|
||||
}
|
||||
|
||||
.rw-number-picker .rw-btn:hover,
|
||||
.rw-number-picker .rw-btn:active {
|
||||
background-color: #e6e6e6
|
||||
}
|
||||
|
||||
.rw-number-picker .rw-btn:active {
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125)
|
||||
}
|
||||
|
||||
.rw-state-disabled .rw-number-picker .rw-btn,
|
||||
.rw-state-readonly .rw-number-picker .rw-btn,
|
||||
fieldset[disabled] .rw-number-picker .rw-btn,
|
||||
.rw-state-disabled .rw-number-picker .rw-btn:hover,
|
||||
.rw-state-readonly .rw-number-picker .rw-btn:hover,
|
||||
fieldset[disabled] .rw-number-picker .rw-btn:hover,
|
||||
.rw-state-disabled .rw-number-picker .rw-btn:active,
|
||||
.rw-state-readonly .rw-number-picker .rw-btn:active,
|
||||
fieldset[disabled] .rw-number-picker .rw-btn:active {
|
||||
cursor: not-allowed;
|
||||
background-color: inherit;
|
||||
background-image: none;
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.rw-number-picker .rw-select {
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.rw-number-picker .rw-select,
|
||||
.rw-number-picker .rw-select:hover,
|
||||
.rw-number-picker .rw-select:active {
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.rw-calendar-popup {
|
||||
right: auto;
|
||||
min-width: 0;
|
||||
width: 18em
|
||||
}
|
||||
|
||||
.rw-calendar {
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
border: #ccc 1px solid;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.rw-calendar.rw-popup {
|
||||
border-color: #ccc
|
||||
}
|
||||
|
||||
.rw-calendar-now {
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
.rw-calendar-btn-left,
|
||||
.rw-calendar-btn-right {
|
||||
width: 12.5%
|
||||
}
|
||||
|
||||
.rw-calendar-btn-view {
|
||||
width: 75%
|
||||
}
|
||||
|
||||
.rw-calendar-footer {
|
||||
border-top: 1px solid #ccc
|
||||
}
|
||||
|
||||
.rw-calendar-grid {
|
||||
outline: none;
|
||||
height: 14.28571429em;
|
||||
table-layout: fixed;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
background-color: #fff
|
||||
}
|
||||
|
||||
.rw-head-cell {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: .25em
|
||||
}
|
||||
|
||||
.rw-cell {
|
||||
color: #333;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
line-height: normal;
|
||||
text-align: center;
|
||||
border: 1px solid transparent;
|
||||
padding: .25em
|
||||
}
|
||||
|
||||
.rw-cell:hover {
|
||||
background-color: #e6e6e6;
|
||||
border-color: #e6e6e6;
|
||||
color: #333
|
||||
}
|
||||
|
||||
.rw-cell.rw-state-focus,
|
||||
.rw-cell.rw-state-focus:hover {
|
||||
background-color: transparent;
|
||||
color: #333
|
||||
}
|
||||
|
||||
.rw-cell.rw-state-selected,
|
||||
.rw-cell.rw-state-selected:hover {
|
||||
background-color: #337ab7;
|
||||
border-color: #337ab7;
|
||||
color: white
|
||||
}
|
||||
|
||||
.rw-cell.rw-state-disabled {
|
||||
color: #999;
|
||||
filter: alpha(opacity=7);
|
||||
opacity: .7
|
||||
}
|
||||
|
||||
.rw-cell.rw-state-disabled:hover {
|
||||
background: none;
|
||||
border-color: transparent
|
||||
}
|
||||
|
||||
.rw-calendar-month .rw-cell {
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.rw-cell-off-range {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.rw-calendar-transition-group {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.rw-calendar-transition {
|
||||
transition: transform 300ms;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.rw-calendar-transition-top {
|
||||
-ms-transform: translateY(-100%);
|
||||
transform: translateY(-100%)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-bottom {
|
||||
-ms-transform: translateY(100%);
|
||||
transform: translateY(100%)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-right {
|
||||
-ms-transform: translateX(-100%);
|
||||
transform: translateX(-100%)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-left {
|
||||
-ms-transform: translateX(100%);
|
||||
transform: translateX(100%)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-entering.rw-calendar-transition-top,
|
||||
.rw-calendar-transition-entered.rw-calendar-transition-top,
|
||||
.rw-calendar-transition-entering.rw-calendar-transition-bottom,
|
||||
.rw-calendar-transition-entered.rw-calendar-transition-bottom {
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-entering.rw-calendar-transition-right,
|
||||
.rw-calendar-transition-entered.rw-calendar-transition-right,
|
||||
.rw-calendar-transition-entering.rw-calendar-transition-left,
|
||||
.rw-calendar-transition-entered.rw-calendar-transition-left {
|
||||
-ms-transform: translateX(0);
|
||||
transform: translateX(0)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-exiting.rw-calendar-transition-top {
|
||||
-ms-transform: translateY(100%);
|
||||
transform: translateY(100%)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-exiting.rw-calendar-transition-bottom {
|
||||
-ms-transform: translateY(-100%);
|
||||
transform: translateY(-100%)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-exiting.rw-calendar-transition-right {
|
||||
-ms-transform: translateX(100%);
|
||||
transform: translateX(100%)
|
||||
}
|
||||
|
||||
.rw-calendar-transition-exiting.rw-calendar-transition-left {
|
||||
-ms-transform: translateX(-100%);
|
||||
transform: translateX(-100%)
|
||||
}
|
||||
|
||||
.rw-select-list {
|
||||
overflow: auto;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.rw-select-list .rw-list {
|
||||
max-height: none;
|
||||
font-size: 1em
|
||||
}
|
||||
|
||||
.rw-select-list-label {
|
||||
display: block;
|
||||
position: relative;
|
||||
font-weight: normal;
|
||||
cursor: inherit;
|
||||
padding-left: 20px;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.rw-rtl .rw-select-list-label {
|
||||
padding-left: 0;
|
||||
padding-right: 20px
|
||||
}
|
||||
|
||||
input.rw-select-list-input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
top: 0.1em /9;
|
||||
margin: 0;
|
||||
line-height: normal;
|
||||
cursor: inherit
|
||||
}
|
||||
|
||||
.rw-rtl input.rw-select-list-input {
|
||||
left: auto;
|
||||
right: 0
|
||||
}
|
||||
|
||||
.rw-loading-mask {
|
||||
content: '';
|
||||
background: url("../img/loader-big.gif") no-repeat center;
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
opacity: .7;
|
||||
filter: alpha(opacity=70);
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.rw-multiselect {
|
||||
cursor: text
|
||||
}
|
||||
|
||||
.rw-multiselect .rw-input-reset {
|
||||
height: calc(2.429em - 2px);
|
||||
margin-top: -2px\9;
|
||||
height: 2.429em\9;
|
||||
border-width: 0;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
padding: 0 .857em
|
||||
}
|
||||
|
||||
.rw-multiselect .rw-select,
|
||||
.rw-multiselect .rw-select:hover,
|
||||
.rw-multiselect .rw-select:active {
|
||||
box-shadow: none;
|
||||
background: none
|
||||
}
|
||||
|
||||
.rw-multiselect-taglist {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
vertical-align: 0;
|
||||
outline: none
|
||||
}
|
||||
|
||||
.rw-multiselect-tag {
|
||||
display: inline-table;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
padding: 0 .35em 0 .35em;
|
||||
margin-left: calc(0.279335em - 1px);
|
||||
margin-top: .279335em;
|
||||
margin-top: calc(0.279335em - 1px);
|
||||
margin-bottom: calc(0.279335em + 2px);
|
||||
height: 1.87033em;
|
||||
border-radius: 4px;
|
||||
background-color: #2598bc;
|
||||
cursor: default;
|
||||
vertical-align: top;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
max-width: 100%
|
||||
}
|
||||
|
||||
.rw-multiselect-tag>* {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
height: 100%
|
||||
}
|
||||
|
||||
.rw-rtl .rw-multiselect-tag {
|
||||
margin-left: 0;
|
||||
margin-right: calc(0.279335em - 1px);
|
||||
padding: 0 .35em 0 .35em
|
||||
}
|
||||
|
||||
.rw-multiselect-tag.rw-state-focus,
|
||||
.rw-multiselect-tag.rw-state-focus:hover {
|
||||
background-color: transparent;
|
||||
color: #333
|
||||
}
|
||||
|
||||
.rw-multiselect-tag.rw-state-readonly,
|
||||
.rw-multiselect-tag.rw-state-disabled,
|
||||
.rw-state-readonly .rw-multiselect-tag,
|
||||
.rw-state-disabled .rw-multiselect-tag,
|
||||
fieldset[disabled] .rw-multiselect-tag {
|
||||
cursor: not-allowed
|
||||
}
|
||||
|
||||
.rw-multiselect-tag.rw-state-disabled,
|
||||
.rw-state-disabled .rw-multiselect-tag,
|
||||
fieldset[disabled] .rw-multiselect-tag {
|
||||
opacity: .65;
|
||||
filter: alpha(opacity=65)
|
||||
}
|
||||
|
||||
fieldset[disabled] .rw-multiselect-tag {
|
||||
box-shadow: none;
|
||||
cursor: not-allowed
|
||||
}
|
||||
|
||||
.rw-multiselect-tag-btn {
|
||||
color: inherit;
|
||||
margin-left: .25em
|
||||
}
|
||||
|
||||
.rw-rtl .rw-multiselect-tag-btn {
|
||||
margin-left: 0;
|
||||
margin-right: .25em
|
||||
}
|
||||
|
||||
.rw-autocomplete .rw-select {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: auto;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0
|
||||
}
|
||||
|
||||
.rw-popup-container {
|
||||
position: absolute;
|
||||
z-index: 1005;
|
||||
top: 100%;
|
||||
left: -6px;
|
||||
right: -6px
|
||||
}
|
||||
|
||||
.rw-popup-container.rw-dropup {
|
||||
top: auto;
|
||||
bottom: 100%
|
||||
}
|
||||
|
||||
.rw-state-focus .rw-popup-container {
|
||||
z-index: 1006
|
||||
}
|
||||
|
||||
.rw-popup-transition {
|
||||
width: 100%;
|
||||
margin-bottom: 6px;
|
||||
padding: 0 6px
|
||||
}
|
||||
|
||||
.rw-dropup>.rw-popup-transition {
|
||||
margin-bottom: 0;
|
||||
margin-top: 6px
|
||||
}
|
||||
|
||||
.rw-popup {
|
||||
border-top-right-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
box-shadow: 0 5px 6px rgba(0, 0, 0, 0.2);
|
||||
border: #ccc 1px solid;
|
||||
background: #fff
|
||||
}
|
||||
|
||||
.rw-dropup .rw-popup {
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-top-right-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.2)
|
||||
}
|
||||
|
||||
.rw-popup-transition {
|
||||
transition: transform 200ms
|
||||
}
|
||||
|
||||
.rw-popup-transition-entering {
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.rw-popup-transition-entering .rw-popup-transition {
|
||||
-ms-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
transition-timing-function: ease-out
|
||||
}
|
||||
|
||||
.rw-popup-transition-exiting .rw-popup-transition {
|
||||
transition-timing-function: ease-in
|
||||
}
|
||||
|
||||
.rw-popup-transition-exiting,
|
||||
.rw-popup-transition-exited {
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.rw-popup-transition-exiting .rw-popup-transition,
|
||||
.rw-popup-transition-exited .rw-popup-transition {
|
||||
-ms-transform: translateY(-100%);
|
||||
transform: translateY(-100%)
|
||||
}
|
||||
|
||||
.rw-popup-transition-exiting.rw-dropup .rw-popup-transition,
|
||||
.rw-popup-transition-exited.rw-dropup .rw-popup-transition {
|
||||
-ms-transform: translateY(100%);
|
||||
transform: translateY(100%)
|
||||
}
|
||||
|
||||
.rw-popup-transition-exited {
|
||||
display: none
|
||||
}
|
||||
|
||||
.rw-state-disabled {
|
||||
box-shadow: none;
|
||||
cursor: not-allowed
|
||||
}
|
5077
accounts/public/assets/css/sail.css
Executable file
207
accounts/public/assets/css/tutorial.css
Executable file
@ -0,0 +1,207 @@
|
||||
.Tutorial-one {
|
||||
padding: 10px;
|
||||
background-image: url('../img/tutorials/1.png');
|
||||
}
|
||||
|
||||
.Info-icon {
|
||||
padding: 10px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
background-image: url('../img/tutorials/info.png');
|
||||
}
|
||||
|
||||
.Tutorial-image--box {
|
||||
height: 220px;
|
||||
width: 520px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.tut-Hide--check{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#slider {
|
||||
height: 35vw;
|
||||
position: relative;
|
||||
perspective: 1000px;
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
#slider label {
|
||||
margin: auto;
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
transition: transform 0.4s ease;
|
||||
}
|
||||
|
||||
#s1:checked ~ #slide4,
|
||||
#s2:checked ~ #slide5,
|
||||
#s3:checked ~ #slide1,
|
||||
#s4:checked ~ #slide2,
|
||||
#s5:checked ~ #slide3 {
|
||||
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, .37);
|
||||
transform: translate3d(-30%, 0, -200px);
|
||||
}
|
||||
|
||||
#s1:checked~#slide5,
|
||||
#s2:checked~#slide1,
|
||||
#s3:checked~#slide2,
|
||||
#s4:checked~#slide3,
|
||||
#s5:checked~#slide4 {
|
||||
box-shadow: 0 6px 10px 0 rgba(0, 0, 0, .3), 0 2px 2px 0 rgba(0, 0, 0, .2);
|
||||
transform: translate3d(-15%, 0, -100px);
|
||||
}
|
||||
|
||||
#s1:checked~#slide1,
|
||||
#s2:checked~#slide2,
|
||||
#s3:checked~#slide3,
|
||||
#s4:checked~#slide4,
|
||||
#s5:checked~#slide5 {
|
||||
box-shadow: 0 13px 25px 0 rgba(0, 0, 0, .3), 0 11px 7px 0 rgba(0, 0, 0, .19);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
#s1:checked~#slide2,
|
||||
#s2:checked~#slide3,
|
||||
#s3:checked~#slide4,
|
||||
#s4:checked~#slide5,
|
||||
#s5:checked~#slide1 {
|
||||
box-shadow: 0 6px 10px 0 rgba(0, 0, 0, .3), 0 2px 2px 0 rgba(0, 0, 0, .2);
|
||||
transform: translate3d(15%, 0, -100px);
|
||||
}
|
||||
|
||||
#s1:checked~#slide3,
|
||||
#s2:checked~#slide4,
|
||||
#s3:checked~#slide5,
|
||||
#s4:checked~#slide1,
|
||||
#s5:checked~#slide2 {
|
||||
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, .37);
|
||||
transform: translate3d(30%, 0, -200px);
|
||||
}
|
||||
|
||||
#slide1 {
|
||||
background: #00BCD4;
|
||||
}
|
||||
|
||||
#slide2 {
|
||||
background: #4CAF50;
|
||||
}
|
||||
|
||||
#slide3 {
|
||||
background: #CDDC39;
|
||||
}
|
||||
|
||||
#slide4 {
|
||||
background: #FFC107;
|
||||
}
|
||||
|
||||
#slide5 {
|
||||
background: #FF5722
|
||||
}
|
||||
|
||||
.tut-Icon--alarm {
|
||||
content: url('../img/tutorials/alarm.png');
|
||||
}
|
||||
|
||||
.tut-Icon--bell {
|
||||
|
||||
content: url('../img/tutorials/bell.png');
|
||||
}
|
||||
|
||||
.tut-Icon--sol {
|
||||
content: url('../img/tutorials/bulb.png');
|
||||
}
|
||||
|
||||
.tut-Icon--info {
|
||||
content: url('../img/tutorials/info.png');
|
||||
}
|
||||
|
||||
.tut-Monitor--ack {
|
||||
margin: 5px;
|
||||
object-fit: fill;
|
||||
object-position: center;
|
||||
content: url('../img/tutorials/ack_rsv.png');
|
||||
}
|
||||
|
||||
.tut-Monitor--metrics {
|
||||
margin: 5px;
|
||||
object-fit: fill;
|
||||
object-position: center;
|
||||
content: url('../img/tutorials/metrics.png');
|
||||
}
|
||||
|
||||
.tut-Monitor--range {
|
||||
margin: 5px;
|
||||
object-fit: fill;
|
||||
object-position: center;
|
||||
content: url('../img/tutorials/range.png');
|
||||
}
|
||||
|
||||
.tut-Monitor--incident {
|
||||
margin: 5px;
|
||||
object-fit: fill;
|
||||
object-position: center;
|
||||
content: url('../img/tutorials/incidents.png');
|
||||
}
|
||||
|
||||
.tut-Monitor--monitor {
|
||||
margin: 5px;
|
||||
object-fit: fill;
|
||||
object-position: center;
|
||||
content: url('../img/tutorials/monitor.png');
|
||||
}
|
||||
|
||||
.bs-Button--icon--right.bs-Button--eye:after,
|
||||
.bs-Button--eye:before {
|
||||
padding-top: 2px;
|
||||
size: 7px;
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAA20lEQVQ4T+3SP0tCURgH4MchCITCVcIhaGoRRPADuPQJkiAo55YGJ50cHAUXNzFaCpzc/QKBg3NjRHOBTi1x4SAi1+4FHRw8cJbz53l5f7wZO16ZHXsO4PaJps0wG0otkkr+B57hHlWcBugHEwzwFYdvAuu4RQdzvITP1zhBC08YrqNx4DNm6OIIr/gOu4Ab/KKBS9ytonFgDVfo4w29AEftHuMRFTxgjFESGN2fo41PRFApfJoihzya+EjT8uqbMoq4CIfvIY4Ijl1pxyZpWpb3BzB1VBsf7n+Gf+YPHxVDqgqmAAAAAElFTkSuQmCC');
|
||||
}
|
||||
|
||||
.bs-Button--icon--right.bs-Button--eye:active:after,
|
||||
.bs-Button--icon--right.bs-Button--eye:focus:hover:after,
|
||||
.bs-Button--icon--right.bs-Button--eye:hover:after,
|
||||
.bs-Button--eye:active:before,
|
||||
.bs-Button--eye:focus:hover:before,
|
||||
.bs-Button--eye:hover:before {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAA20lEQVQ4T+3SP0tCURgH4MchCITCVcIhaGoRRPADuPQJkiAo55YGJ50cHAUXNzFaCpzc/QKBg3NjRHOBTi1x4SAi1+4FHRw8cJbz53l5f7wZO16ZHXsO4PaJps0wG0otkkr+B57hHlWcBugHEwzwFYdvAuu4RQdzvITP1zhBC08YrqNx4DNm6OIIr/gOu4Ab/KKBS9ytonFgDVfo4w29AEftHuMRFTxgjFESGN2fo41PRFApfJoihzya+EjT8uqbMoq4CIfvIY4Ijl1pxyZpWpb3BzB1VBsf7n+Gf+YPHxVDqgqmAAAAAElFTkSuQmCC');
|
||||
}
|
||||
|
||||
.bs-Button--blue.bs-Button--eye:before,
|
||||
.bs-Button--blue.bs-Button--eye:hover:before,
|
||||
.bs-Button--icon--right.bs-Button--blue.bs-Button--eye:after,
|
||||
.bs-Button--icon--right.bs-Button--blue.bs-Button--eye:hover:after,
|
||||
.bs-Button--icon--right.bs-Button--eye.bs-Button--blue.bs-is-disabled:after,
|
||||
.bs-Button--icon--right.bs-Button--eye.bs-Button--blue:disabled:after,
|
||||
.bs-Button--eye.bs-Button--blue.bs-is-disabled:before,
|
||||
.bs-Button--eye.bs-Button--blue:disabled:before {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAA20lEQVQ4T+3SP0tCURgH4MchCITCVcIhaGoRRPADuPQJkiAo55YGJ50cHAUXNzFaCpzc/QKBg3NjRHOBTi1x4SAi1+4FHRw8cJbz53l5f7wZO16ZHXsO4PaJps0wG0otkkr+B57hHlWcBugHEwzwFYdvAuu4RQdzvITP1zhBC08YrqNx4DNm6OIIr/gOu4Ab/KKBS9ytonFgDVfo4w29AEftHuMRFTxgjFESGN2fo41PRFApfJoihzya+EjT8uqbMoq4CIfvIY4Ijl1pxyZpWpb3BzB1VBsf7n+Gf+YPHxVDqgqmAAAAAElFTkSuQmCC');
|
||||
}
|
||||
.bs-Button--icon--right.bs-Button--link.bs-Button--eye:after,
|
||||
.bs-Button--link.bs-Button--eye:before {
|
||||
height: 10px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAA20lEQVQ4T+3SP0tCURgH4MchCITCVcIhaGoRRPADuPQJkiAo55YGJ50cHAUXNzFaCpzc/QKBg3NjRHOBTi1x4SAi1+4FHRw8cJbz53l5f7wZO16ZHXsO4PaJps0wG0otkkr+B57hHlWcBugHEwzwFYdvAuu4RQdzvITP1zhBC08YrqNx4DNm6OIIr/gOu4Ab/KKBS9ytonFgDVfo4w29AEftHuMRFTxgjFESGN2fo41PRFApfJoihzya+EjT8uqbMoq4CIfvIY4Ijl1pxyZpWpb3BzB1VBsf7n+Gf+YPHxVDqgqmAAAAAElFTkSuQmCC');
|
||||
}
|
||||
.bs-Button--icon--right.bs-Button--link.bs-Button--eye:active:after,
|
||||
.bs-Button--icon--right.bs-Button--link.bs-Button--eye:hover:after,
|
||||
.bs-Button--link.bs-Button--eye:active:before,
|
||||
.bs-Button--link.bs-Button--eye:hover:before {
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+c2V0dGluZ3MtLWhvdmVyPC90aXRsZT48cGF0aCBkPSJNMTQuNDI2IDkuMjk4Yy0uMTY0IDAtMS4xNDcgMC0xLjU1Ny0uNDk2IDAtLjA4My0uMDgyLS4wODMtLjA4Mi0uMTY2LS4wODItLjU3OC42NTYtMS4zMjIuNzM4LTEuNDA1LjE2NC0uMTY1LjE2NC0uNDEzLjA4Mi0uNDk1LS4wODItLjA4My0uNDEtLjQxNC0uNDkyLS41NzktLjA4Mi0uMTY1LS4zMjgtLjA4My0uNDkyLjA4My0uMTY0LjE2NS0uODIuODI2LTEuMzkzLjc0My0uMDgyIDAtLjA4Mi0uMDgyLS4xNjQtLjA4Mi0uNDkyLS4zMy0uNDkyLTEuMzIyLS40OTItMS40ODggMC0uMjQ4LS4wODItLjQxMy0uMjQ2LS40MTNoLS44MmMtLjE2NCAwLS4yNDYuMTY1LS4yNDYuNDEzIDAgLjE2NiAwIDEuMTU3LS40OTIgMS41Ny0uMDgxIDAtLjA4MS4wODMtLjE2My4wODMtLjU3NCAwLTEuMjMtLjY2MS0xLjM5NC0uODI2LS4xNjQtLjE2Ni0uNDEtLjE2Ni0uNDkyLS4wODMtLjA4Mi4xNjUtLjQxLjQ5Ni0uNTczLjU3OS0uMDgyLjA4Mi0uMDgyLjMzLjA4Mi40OTUuMTYzLjE2Ni44Mi44MjcuNzM3IDEuNDA1IDAgLjA4My0uMDgyLjA4My0uMDgyLjE2Ni0uMzI4LjQ5Ni0xLjMxMS40OTYtMS40NzUuNDk2LS4yNDYgMC0uNDEuMDgyLS40MS4yNDd2Ljc0NGMwIC4xNjYuMTY0LjMzLjQxLjMzLjE2NCAwIDEuMTQ3IDAgMS41NTcuNDk3IDAgLjA4Mi4wODIuMDgyLjA4Mi4xNjUuMDgyLjU3OS0uNjU2IDEuMzIyLS43MzggMS40MDUtLjE2My4xNjUtLjE2My40MTMtLjA4MS40OTYuMDgxLjA4Mi40MS40MTMuNDkxLjU3OC4wODIuMDgzLjMyOC4wODMuNDkyLS4wODIuMTY0LS4xNjYuODItLjgyNyAxLjM5NC0uNzQ0LjA4MiAwIC4wODIuMDgzLjE2My4wODMuNDkyLjQxMy40OTIgMS4zMjIuNDkyIDEuNTcgMCAuMTY1LjE2NC40MTMuMzI4LjQxM2guNzM4Yy4xNjQgMCAuMzI4LS4xNjUuMzI4LS40MTMgMC0uMTY2IDAtMS4xNTcuNDkyLTEuNTcuMDgyIDAgLjA4Mi0uMDgzLjE2My0uMDgzLjU3NC0uMDgzIDEuMzEyLjY2MSAxLjM5NC43NDQuMTY0LjE2NS40MS4xNjUuNDkyLjA4MmwuNTczLS41NzhjLjA4Mi0uMDgzLjA4Mi0uMzMtLjA4MS0uNDk2LS4xNjQtLjE2NS0uODItLjgyNi0uNzM4LTEuNDA1IDAtLjA4My4wODItLjA4My4wODItLjE2NS40MS0uNDk2IDEuMzExLS40OTYgMS41NTctLjQ5Ni4xNjQgMCAuNDEtLjE2NS40MS0uMzN2LS43NDVhLjc0MS43NDEgMCAwIDAtLjU3NC0uMjQ3ek0xMCAxMi4wMzNjLTEuMDkgMC0yLS45MTctMi0yLjAxNkM4IDguOTE3IDguOTEgOCAxMCA4YzEuMDkgMCAyIC45MTcgMiAyLjAxNyAwIDEuMS0uOTEgMi4wMTYtMiAyLjAxNnoiIGZpbGw9IiMzMjMyNUQiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==');
|
||||
}
|
||||
.bs-Button--icon--right.bs-Button--eye.bs-is-disabled:after,
|
||||
.bs-Button--icon--right.bs-Button--eye:disabled:after,
|
||||
.bs-Button--link.bs-Button--icon--right.bs-Button--eye.bs-is-disabled:after,
|
||||
.bs-Button--link.bs-Button--icon--right.bs-Button--eye:disabled:after,
|
||||
.bs-Button--link.bs-Button--eye.bs-is-disabled:before,
|
||||
.bs-Button--link.bs-Button--eye:disabled:before,
|
||||
.bs-Button--eye.bs-is-disabled:before,
|
||||
.bs-Button--eye:disabled:before {
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+c2V0dGluZ3MtLWRpc2FibGVkPC90aXRsZT48cGF0aCBkPSJNMTQuNDI2IDkuMjk4Yy0uMTY0IDAtMS4xNDcgMC0xLjU1Ny0uNDk2IDAtLjA4My0uMDgyLS4wODMtLjA4Mi0uMTY2LS4wODItLjU3OC42NTYtMS4zMjIuNzM4LTEuNDA1LjE2NC0uMTY1LjE2NC0uNDEzLjA4Mi0uNDk1LS4wODItLjA4My0uNDEtLjQxNC0uNDkyLS41NzktLjA4Mi0uMTY1LS4zMjgtLjA4My0uNDkyLjA4My0uMTY0LjE2NS0uODIuODI2LTEuMzkzLjc0My0uMDgyIDAtLjA4Mi0uMDgyLS4xNjQtLjA4Mi0uNDkyLS4zMy0uNDkyLTEuMzIyLS40OTItMS40ODggMC0uMjQ4LS4wODItLjQxMy0uMjQ2LS40MTNoLS44MmMtLjE2NCAwLS4yNDYuMTY1LS4yNDYuNDEzIDAgLjE2NiAwIDEuMTU3LS40OTIgMS41Ny0uMDgxIDAtLjA4MS4wODMtLjE2My4wODMtLjU3NCAwLTEuMjMtLjY2MS0xLjM5NC0uODI2LS4xNjQtLjE2Ni0uNDEtLjE2Ni0uNDkyLS4wODMtLjA4Mi4xNjUtLjQxLjQ5Ni0uNTczLjU3OS0uMDgyLjA4Mi0uMDgyLjMzLjA4Mi40OTUuMTYzLjE2Ni44Mi44MjcuNzM3IDEuNDA1IDAgLjA4My0uMDgyLjA4My0uMDgyLjE2Ni0uMzI4LjQ5Ni0xLjMxMS40OTYtMS40NzUuNDk2LS4yNDYgMC0uNDEuMDgyLS40MS4yNDd2Ljc0NGMwIC4xNjYuMTY0LjMzLjQxLjMzLjE2NCAwIDEuMTQ3IDAgMS41NTcuNDk3IDAgLjA4Mi4wODIuMDgyLjA4Mi4xNjUuMDgyLjU3OS0uNjU2IDEuMzIyLS43MzggMS40MDUtLjE2My4xNjUtLjE2My40MTMtLjA4MS40OTYuMDgxLjA4Mi40MS40MTMuNDkxLjU3OC4wODIuMDgzLjMyOC4wODMuNDkyLS4wODIuMTY0LS4xNjYuODItLjgyNyAxLjM5NC0uNzQ0LjA4MiAwIC4wODIuMDgzLjE2My4wODMuNDkyLjQxMy40OTIgMS4zMjIuNDkyIDEuNTcgMCAuMTY1LjE2NC40MTMuMzI4LjQxM2guNzM4Yy4xNjQgMCAuMzI4LS4xNjUuMzI4LS40MTMgMC0uMTY2IDAtMS4xNTcuNDkyLTEuNTcuMDgyIDAgLjA4Mi0uMDgzLjE2My0uMDgzLjU3NC0uMDgzIDEuMzEyLjY2MSAxLjM5NC43NDQuMTY0LjE2NS40MS4xNjUuNDkyLjA4MmwuNTczLS41NzhjLjA4Mi0uMDgzLjA4Mi0uMzMtLjA4MS0uNDk2LS4xNjQtLjE2NS0uODItLjgyNi0uNzM4LTEuNDA1IDAtLjA4My4wODItLjA4My4wODItLjE2NS40MS0uNDk2IDEuMzExLS40OTYgMS41NTctLjQ5Ni4xNjQgMCAuNDEtLjE2NS40MS0uMzN2LS43NDVhLjc0MS43NDEgMCAwIDAtLjU3NC0uMjQ3ek0xMCAxMi4wMzNjLTEuMDkgMC0yLS45MTctMi0yLjAxNkM4IDguOTE3IDguOTEgOCAxMCA4YzEuMDkgMCAyIC45MTcgMiAyLjAxNyAwIDEuMS0uOTEgMi4wMTYtMiAyLjAxNnoiIGZpbGw9IiM4ODk4QUEiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==');
|
||||
}
|
BIN
accounts/public/assets/fonts/camphor/font1.woff2
Executable file
BIN
accounts/public/assets/fonts/camphor/font2.woff2
Executable file
BIN
accounts/public/assets/fonts/camphor/font3.woff2
Executable file
BIN
accounts/public/assets/fonts/camphor/font4.woff2
Executable file
BIN
accounts/public/assets/fonts/rw-widgets.eot
Executable file
24
accounts/public/assets/fonts/rw-widgets.svg
Executable file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
|
||||
<defs>
|
||||
<font id="rw-widgets" horiz-adv-x="1000" >
|
||||
<font-face font-family="rw-widgets" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||
<missing-glyph horiz-adv-x="1000" />
|
||||
<glyph glyph-name="up-dir" unicode="" d="M571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" />
|
||||
|
||||
<glyph glyph-name="search" unicode="" d="M643 386q0 103-73 176t-177 74-177-74-73-176 73-177 177-73 177 73 73 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 153-31 125-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
|
||||
|
||||
<glyph glyph-name="down-dir" unicode="" d="M571 457q0-14-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25t11 25 25 11h500q14 0 25-11t10-25z" horiz-adv-x="571.4" />
|
||||
|
||||
<glyph glyph-name="calendar" unicode="" d="M71-79h161v161h-161v-161z m197 0h178v161h-178v-161z m-197 197h161v178h-161v-178z m197 0h178v178h-178v-178z m-197 214h161v161h-161v-161z m411-411h179v161h-179v-161z m-214 411h178v161h-178v-161z m428-411h161v161h-161v-161z m-214 197h179v178h-179v-178z m-196 482v161q0 7-6 12t-12 6h-36q-7 0-12-6t-6-12v-161q0-7 6-13t12-5h36q7 0 12 5t6 13z m410-482h161v178h-161v-178z m-214 214h179v161h-179v-161z m214 0h161v161h-161v-161z m18 268v161q0 7-5 12t-13 6h-35q-7 0-13-6t-5-12v-161q0-7 5-13t13-5h35q8 0 13 5t5 13z m215 36v-715q0-29-22-50t-50-21h-786q-29 0-50 21t-21 50v715q0 29 21 50t50 21h72v54q0 37 26 63t63 26h36q37 0 63-26t26-63v-54h214v54q0 37 27 63t63 26h35q37 0 64-26t26-63v-54h71q29 0 50-21t22-50z" horiz-adv-x="928.6" />
|
||||
|
||||
<glyph glyph-name="clock" unicode="" d="M500 546v-250q0-7-5-12t-13-5h-178q-8 0-13 5t-5 12v36q0 8 5 13t13 5h125v196q0 8 5 13t12 5h36q8 0 13-5t5-13z m232-196q0 83-41 152t-110 111-152 41-153-41-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152z m125 0q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="angle-left" unicode="" d="M350 546q0-7-6-12l-219-220 219-219q6-6 6-13t-6-13l-28-28q-5-5-12-5t-13 5l-260 261q-6 5-6 12t6 13l260 260q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="357.1" />
|
||||
|
||||
<glyph glyph-name="angle-right" unicode="" d="M332 314q0-7-5-12l-261-261q-5-5-12-5t-13 5l-28 28q-6 6-6 13t6 13l219 219-219 220q-6 5-6 12t6 13l28 28q5 6 13 6t12-6l261-260q5-5 5-13z" horiz-adv-x="357.1" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
BIN
accounts/public/assets/fonts/rw-widgets.ttf
Executable file
BIN
accounts/public/assets/fonts/rw-widgets.woff
Executable file
BIN
accounts/public/assets/fonts/rw-widgets.woff2
Executable file
4
accounts/public/assets/img/acknowledge.svg
Executable file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 52 52" style="enable-background:new 0 0 52 52;" xml:space="preserve" width="512px" height="512px" class=""><g><g>
|
||||
<path d="M26,0C11.664,0,0,11.663,0,26s11.664,26,26,26s26-11.663,26-26S40.336,0,26,0z M40.495,17.329l-16,18 C24.101,35.772,23.552,36,22.999,36c-0.439,0-0.88-0.144-1.249-0.438l-10-8c-0.862-0.689-1.002-1.948-0.312-2.811 c0.689-0.863,1.949-1.003,2.811-0.313l8.517,6.813l14.739-16.581c0.732-0.826,1.998-0.9,2.823-0.166 C41.154,15.239,41.229,16.503,40.495,17.329z" data-original="#000000" class="active-path" data-old_color="#FFE000" fill="#FFEF00"/>
|
||||
</g></g> </svg>
|
After Width: | Height: | Size: 742 B |
15
accounts/public/assets/img/black-svg-full.svg
Executable file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="566.38" height="275.072" viewBox="0 0 566.38 275.07" enable-background="new 0 0 566.38 275.07" xml:space="preserve">
|
||||
<rect x="0" y="3.05176e-005" fill="#FFFFFF" fill-opacity="0" stroke-width="0.2" stroke-linejoin="round" width="566.38" height="275.072"/>
|
||||
<g>
|
||||
<path fill="#32325D" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 219.416,91.5147C 217.198,90.5867 214.668,90.1228 211.826,90.1228C 203.852,90.1228 199.865,94.4217 199.865,103.019L 199.865,112.393L 216.632,112.393L 216.632,124.919L 199.93,124.919L 199.93,181.986L 184.619,181.986L 184.619,124.919L 172.093,124.919L 172.093,112.393L 184.619,112.393L 184.619,101.171C 184.619,93.878 187.044,88.1256 191.894,83.9138C 196.744,79.7019 202.808,77.596 210.086,77.596C 214.015,77.596 217.125,78.0092 219.416,78.8356L 219.416,91.5147 Z "/>
|
||||
<path fill="#32325D" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 291.097,112.393L 259.324,193.252C 252.669,208.011 243.339,215.391 231.334,215.391C 227.97,215.391 225.158,215.101 222.896,214.521L 222.896,201.472C 225.448,202.4 227.76,202.864 229.833,202.864C 235.85,202.864 240.345,199.856 243.317,193.839L 248.102,181.986L 220.112,112.393L 237.576,112.393L 254.539,163.065C 254.728,163.703 255.148,165.385 255.8,168.111L 256.148,168.111C 256.38,167.067 256.794,165.429 257.388,163.196L 275.2,112.393L 291.097,112.393 Z "/>
|
||||
<rect x="300.84" y="112.393" fill="#32325D" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" width="15.3105" height="69.5934"/>
|
||||
<path fill="#32325D" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 352.622,171.46L 352.34,171.46L 352.34,213.999L 337.029,213.999L 337.029,112.393L 352.34,112.393L 352.34,124.811L 352.622,124.811C 358.103,115.604 366.121,111.001 376.676,111.001C 385.665,111.001 392.671,114.093 397.695,120.276C 402.719,126.46 405.231,134.764 405.231,145.189C 405.231,156.744 402.396,165.998 396.727,172.95C 391.058,179.902 383.316,183.378 373.5,183.378C 364.468,183.378 357.508,179.405 352.622,171.46 Z M 352.209,144.253L 352.209,152.8C 352.209,157.831 353.844,162.098 357.113,165.599C 360.383,169.1 364.54,170.851 369.586,170.851C 375.487,170.851 380.119,168.597 383.483,164.088C 386.846,159.579 388.528,153.286 388.528,145.21C 388.528,138.425 386.962,133.115 383.831,129.28C 380.699,125.445 376.451,123.528 371.086,123.528C 365.417,123.528 360.854,125.503 357.396,129.454C 353.938,133.405 352.209,138.338 352.209,144.253 Z "/>
|
||||
<path fill="#32325D" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 481.784,151.365L 433.068,151.365C 433.257,157.599 435.294,162.406 439.179,165.784C 443.065,169.162 448.408,170.851 455.207,170.851C 462.834,170.851 469.837,168.531 476.216,163.892L 476.216,177.136C 469.663,181.297 461.007,183.378 450.249,183.378C 439.679,183.378 431.39,180.239 425.38,173.961C 419.37,167.683 416.366,158.846 416.366,147.45C 416.366,136.692 419.671,127.928 426.283,121.157C 432.894,114.386 441.108,111.001 450.923,111.001C 460.739,111.001 468.336,114.035 473.715,120.102C 479.094,126.17 481.784,134.59 481.784,145.363L 481.784,151.365 Z M 465.081,140.23C 465.038,134.953 463.711,130.849 461.101,127.921C 458.491,124.992 454.888,123.528 450.292,123.528C 445.783,123.528 441.967,125.068 438.842,128.149C 435.718,131.23 433.793,135.257 433.068,140.23L 465.081,140.23 Z "/>
|
||||
</g>
|
||||
<path fill="#6CDB56" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 138.368,85.8314L 152.867,85.8314C 155.076,85.8314 156.867,87.6222 156.867,89.8314L 156.867,177.826C 156.867,180.036 155.076,181.826 152.867,181.826L 138.368,181.826C 136.159,181.826 134.368,180.036 134.368,177.826L 134.368,89.8314C 134.368,87.6222 136.159,85.8314 138.368,85.8314 Z "/>
|
||||
<path fill="#6CDB56" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 106.62,86.581L 121.119,86.581C 123.328,86.581 125.119,88.3719 125.119,90.581L 125.119,178.576C 125.119,180.785 123.328,182.576 121.119,182.576L 106.62,182.576C 104.411,182.576 102.62,180.785 102.62,178.576L 102.62,90.581C 102.62,88.3719 104.411,86.581 106.62,86.581 Z "/>
|
||||
<path fill="#6CDB56" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 74.1223,86.0808L 88.6212,86.0808C 90.8303,86.0808 92.6212,87.8717 92.6212,90.0808L 92.6212,178.076C 92.6212,180.285 90.8303,182.076 88.6212,182.076L 74.1223,182.076C 71.9131,182.076 70.1223,180.285 70.1223,178.076L 70.1223,90.0808C 70.1223,87.8717 71.9131,86.0808 74.1223,86.0808 Z "/>
|
||||
</svg>
|
4
accounts/public/assets/img/closebutton.svg
Executable file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 212.982 212.982" style="enable-background:new 0 0 212.982 212.982;" xml:space="preserve" width="512px" height="512px" class=""><g><g id="Close">
|
||||
<path d="M131.804,106.491l75.936-75.936c6.99-6.99,6.99-18.323,0-25.312 c-6.99-6.99-18.322-6.99-25.312,0l-75.937,75.937L30.554,5.242c-6.99-6.99-18.322-6.99-25.312,0c-6.989,6.99-6.989,18.323,0,25.312 l75.937,75.936L5.242,182.427c-6.989,6.99-6.989,18.323,0,25.312c6.99,6.99,18.322,6.99,25.312,0l75.937-75.937l75.937,75.937 c6.989,6.99,18.322,6.99,25.312,0c6.99-6.99,6.99-18.322,0-25.312L131.804,106.491z" data-original="#000000" class="active-path" data-old_color="#6b7c93" fill="#6b7c93"/>
|
||||
</g></g> </svg>
|
After Width: | Height: | Size: 816 B |
48
accounts/public/assets/img/icons/acceptance.svg
Executable file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="612px" height="612px" viewBox="0 0 612 612" style="enable-background:new 0 0 612 612;" xml:space="preserve">
|
||||
<g>
|
||||
<g id="Check">
|
||||
<g>
|
||||
<path d="M306,0C137.012,0,0,137.012,0,306s137.012,306,306,306s306-137.012,306-306S474.988,0,306,0z M306,554.625
|
||||
C168.912,554.625,57.375,443.088,57.375,306S168.912,57.375,306,57.375S554.625,168.912,554.625,306S443.088,554.625,306,554.625
|
||||
z M431.46,210.604c-7.707-0.325-15.529,2.276-21.42,8.186L277.312,351.498l-75.353-75.333c-5.891-5.91-13.712-8.492-21.42-8.186
|
||||
c-6.942,0.287-13.847,2.869-19.144,8.186c-5.298,5.298-7.899,12.202-8.186,19.144c-0.325,7.708,2.276,15.53,8.186,21.42
|
||||
l95.625,95.625c5.604,5.604,12.948,8.396,20.292,8.396s14.688-2.792,20.292-8.396l153-153c5.909-5.91,8.491-13.712,8.186-21.42
|
||||
c-0.287-6.942-2.869-13.846-8.186-19.144C445.287,213.473,438.402,210.872,431.46,210.604z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
52
accounts/public/assets/img/icons/edit.svg
Executable file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 55.25 55.25" style="enable-background:new 0 0 55.25 55.25;" xml:space="preserve">
|
||||
<path d="M52.618,2.631c-3.51-3.508-9.219-3.508-12.729,0L3.827,38.693C3.81,38.71,3.8,38.731,3.785,38.749
|
||||
c-0.021,0.024-0.039,0.05-0.058,0.076c-0.053,0.074-0.094,0.153-0.125,0.239c-0.009,0.026-0.022,0.049-0.029,0.075
|
||||
c-0.003,0.01-0.009,0.02-0.012,0.03l-3.535,14.85c-0.016,0.067-0.02,0.135-0.022,0.202C0.004,54.234,0,54.246,0,54.259
|
||||
c0.001,0.114,0.026,0.225,0.065,0.332c0.009,0.025,0.019,0.047,0.03,0.071c0.049,0.107,0.11,0.21,0.196,0.296
|
||||
c0.095,0.095,0.207,0.168,0.328,0.218c0.121,0.05,0.25,0.075,0.379,0.075c0.077,0,0.155-0.009,0.231-0.027l14.85-3.535
|
||||
c0.027-0.006,0.051-0.021,0.077-0.03c0.034-0.011,0.066-0.024,0.099-0.039c0.072-0.033,0.139-0.074,0.201-0.123
|
||||
c0.024-0.019,0.049-0.033,0.072-0.054c0.008-0.008,0.018-0.012,0.026-0.02l36.063-36.063C56.127,11.85,56.127,6.14,52.618,2.631z
|
||||
M51.204,4.045c2.488,2.489,2.7,6.397,0.65,9.137l-9.787-9.787C44.808,1.345,48.716,1.557,51.204,4.045z M46.254,18.895l-9.9-9.9
|
||||
l1.414-1.414l9.9,9.9L46.254,18.895z M4.961,50.288c-0.391-0.391-1.023-0.391-1.414,0L2.79,51.045l2.554-10.728l4.422-0.491
|
||||
l-0.569,5.122c-0.004,0.038,0.01,0.073,0.01,0.11c0,0.038-0.014,0.072-0.01,0.11c0.004,0.033,0.021,0.06,0.028,0.092
|
||||
c0.012,0.058,0.029,0.111,0.05,0.165c0.026,0.065,0.057,0.124,0.095,0.181c0.031,0.046,0.062,0.087,0.1,0.127
|
||||
c0.048,0.051,0.1,0.094,0.157,0.134c0.045,0.031,0.088,0.06,0.138,0.084C9.831,45.982,9.9,46,9.972,46.017
|
||||
c0.038,0.009,0.069,0.03,0.108,0.035c0.036,0.004,0.072,0.006,0.109,0.006c0,0,0.001,0,0.001,0c0,0,0.001,0,0.001,0h0.001
|
||||
c0,0,0.001,0,0.001,0c0.036,0,0.073-0.002,0.109-0.006l5.122-0.569l-0.491,4.422L4.204,52.459l0.757-0.757
|
||||
C5.351,51.312,5.351,50.679,4.961,50.288z M17.511,44.809L39.889,22.43c0.391-0.391,0.391-1.023,0-1.414s-1.023-0.391-1.414,0
|
||||
L16.097,43.395l-4.773,0.53l0.53-4.773l22.38-22.378c0.391-0.391,0.391-1.023,0-1.414s-1.023-0.391-1.414,0L10.44,37.738
|
||||
l-3.183,0.354L34.94,10.409l9.9,9.9L17.157,47.992L17.511,44.809z M49.082,16.067l-9.9-9.9l1.415-1.415l9.9,9.9L49.082,16.067z"/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
60
accounts/public/assets/img/icons/recycle-bin.svg
Executable file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="56.061px" height="56.062px" viewBox="0 0 56.061 56.062" style="enable-background:new 0 0 56.061 56.062;"
|
||||
xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M40.149,12.335H15.914c-2.02,0-3.661,1.653-3.661,3.694l1.653,36.37c0,2.021,1.644,3.662,3.662,3.662h20.926
|
||||
c2.021,0,3.662-1.632,3.662-3.63l1.653-36.436C43.811,13.979,42.166,12.335,40.149,12.335z M38.492,52.447l-20.971-0.078
|
||||
l-1.654-36.372c0-0.024,0.021-0.046,0.047-0.046l24.28,0.014L38.492,52.447z"/>
|
||||
<path d="M28.05,50.393c1.069,0,1.94-0.87,1.94-1.939V22.23c0-1.068-0.869-1.938-1.94-1.938c-1.068,0-1.938,0.87-1.938,1.938
|
||||
v26.223C26.113,49.522,26.981,50.393,28.05,50.393z"/>
|
||||
<path d="M35.069,50.392h0.02c1.059,0,1.93-0.859,1.941-1.918l0.299-26.22c0.006-0.519-0.189-1.007-0.553-1.378
|
||||
c-0.364-0.371-0.846-0.578-1.387-0.584c-1.06,0-1.929,0.859-1.939,1.917l-0.301,26.22C33.139,49.499,33.998,50.38,35.069,50.392z"
|
||||
/>
|
||||
<path d="M20.972,50.392h0.02c1.07-0.013,1.931-0.894,1.918-1.963l-0.299-26.22c-0.012-1.058-0.883-1.917-1.961-1.917
|
||||
c-0.52,0.006-1.004,0.213-1.367,0.584c-0.362,0.371-0.557,0.859-0.551,1.378l0.299,26.22
|
||||
C19.042,49.532,19.914,50.392,20.972,50.392z"/>
|
||||
<path d="M14.707,10.91l27.086-1.562c0.468-0.026,0.896-0.233,1.209-0.585c0.312-0.35,0.47-0.8,0.438-1.266
|
||||
c-0.053-0.929-0.819-1.653-1.75-1.653L14.604,7.406c-0.467,0.026-0.896,0.233-1.207,0.585c-0.312,0.35-0.471,0.8-0.44,1.267
|
||||
C13.006,10.184,13.776,10.91,14.707,10.91z M14.707,10.396C14.707,10.396,14.707,10.397,14.707,10.396v0.014V10.396z"/>
|
||||
<path d="M23.854,6.294l0.104-0.003c0.481-0.027,0.926-0.241,1.245-0.603c0.322-0.36,0.484-0.824,0.455-1.307l0.021-0.49
|
||||
l4.833-0.232l0.025,0.44c0.057,0.956,0.848,1.704,1.803,1.704L32.446,5.8c0.482-0.028,0.926-0.242,1.246-0.603
|
||||
c0.322-0.36,0.481-0.825,0.455-1.308l-0.025-0.439c-0.115-2.007-1.848-3.553-3.865-3.445L25.47,0.281
|
||||
c-2.017,0.115-3.562,1.852-3.443,3.866l0.025,0.441C22.106,5.546,22.897,6.294,23.854,6.294z M23.854,5.783L23.854,5.783v0.013
|
||||
V5.783z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
40
accounts/public/assets/img/information.svg
Executable file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path d="M256,0C114.613,0,0,114.617,0,256c0,141.391,114.613,256,256,256s256-114.609,256-256C512,114.617,397.387,0,256,0z
|
||||
M256,128c17.674,0,32,14.328,32,32c0,17.68-14.326,32-32,32s-32-14.32-32-32C224,142.328,238.326,128,256,128z M304,384h-96
|
||||
c-8.836,0-16-7.156-16-16c0-8.836,7.164-16,16-16h16v-96h-16c-8.836,0-16-7.156-16-16c0-8.836,7.164-16,16-16h64
|
||||
c8.836,0,16,7.164,16,16v112h16c8.836,0,16,7.164,16,16C320,376.844,312.836,384,304,384z"/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
2
accounts/public/assets/img/monitoraddremove.svg
Executable file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve" width="512px" height="512px" class=""><g><path d="M256,0C114.613,0,0,114.617,0,256c0,141.391,114.613,256,256,256s256-114.609,256-256C512,114.617,397.387,0,256,0z M256,128c17.674,0,32,14.328,32,32c0,17.68-14.326,32-32,32s-32-14.32-32-32C224,142.328,238.326,128,256,128z M304,384h-96 c-8.836,0-16-7.156-16-16c0-8.836,7.164-16,16-16h16v-96h-16c-8.836,0-16-7.156-16-16c0-8.836,7.164-16,16-16h64 c8.836,0,16,7.164,16,16v112h16c8.836,0,16,7.164,16,16C320,376.844,312.836,384,304,384z" data-original="#000000" class="active-path" data-old_color="#14aad9" fill="#14aad9"/></g> </svg>
|
After Width: | Height: | Size: 813 B |
4
accounts/public/assets/img/resolve.svg
Executable file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 52 52" style="enable-background:new 0 0 52 52;" xml:space="preserve" width="512px" height="512px" class=""><g><g>
|
||||
<path d="M26,0C11.664,0,0,11.663,0,26s11.664,26,26,26s26-11.663,26-26S40.336,0,26,0z M40.495,17.329l-16,18 C24.101,35.772,23.552,36,22.999,36c-0.439,0-0.88-0.144-1.249-0.438l-10-8c-0.862-0.689-1.002-1.948-0.312-2.811 c0.689-0.863,1.949-1.003,2.811-0.313l8.517,6.813l14.739-16.581c0.732-0.826,1.998-0.9,2.823-0.166 C41.154,15.239,41.229,16.503,40.495,17.329z" data-original="#000000" class="active-path" data-old_color="#00FF33" fill="#00FF2B"/>
|
||||
</g></g> </svg>
|
After Width: | Height: | Size: 742 B |
42
accounts/public/assets/img/show-more-button.svg
Executable file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="459px" height="459px" viewBox="0 0 459 459" style="enable-background:new 0 0 459 459;" xml:space="preserve">
|
||||
<g>
|
||||
<g id="unfold-more">
|
||||
<path d="M229.5,71.4l81.6,81.6l35.7-35.7L229.5,0L112.2,117.3l35.7,35.7L229.5,71.4z M229.5,387.6L147.9,306l-35.7,35.7L229.5,459
|
||||
l117.3-117.3L311.1,306L229.5,387.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 831 B |
38
accounts/public/assets/img/success.svg
Executable file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<circle style="fill:#25AE88;" cx="25" cy="25" r="25"/>
|
||||
<polyline style="fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" points="
|
||||
38,15 22,33 12,25 "/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 701 B |
BIN
accounts/public/assets/img/tutorials/1.png
Executable file
After Width: | Height: | Size: 12 KiB |
BIN
accounts/public/assets/img/tutorials/ack_rsv.png
Executable file
After Width: | Height: | Size: 18 KiB |
BIN
accounts/public/assets/img/tutorials/alarm.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
accounts/public/assets/img/tutorials/bell.png
Executable file
After Width: | Height: | Size: 28 KiB |
BIN
accounts/public/assets/img/tutorials/bulb.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
accounts/public/assets/img/tutorials/incidents.png
Executable file
After Width: | Height: | Size: 23 KiB |
BIN
accounts/public/assets/img/tutorials/info.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
accounts/public/assets/img/tutorials/metrics.png
Executable file
After Width: | Height: | Size: 6.3 KiB |
BIN
accounts/public/assets/img/tutorials/monitor.png
Executable file
After Width: | Height: | Size: 17 KiB |
BIN
accounts/public/assets/img/tutorials/monitors.png
Executable file
After Width: | Height: | Size: 55 KiB |
BIN
accounts/public/assets/img/tutorials/range.png
Executable file
After Width: | Height: | Size: 463 B |
38
accounts/public/assets/img/warning.svg
Executable file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<circle style="fill:#EFCE4A;" cx="25" cy="25" r="25"/>
|
||||
<line style="fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;" x1="25" y1="10" x2="25" y2="32"/>
|
||||
<line style="fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;" x1="25" y1="37" x2="25" y2="39"/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 808 B |
9
accounts/public/assets/js/landing.base.js
Executable file
@ -0,0 +1,9 @@
|
||||
$(document).ready(function() {
|
||||
setTimeout(()=>{
|
||||
$('div.bar').tipsy({
|
||||
gravity: 'se',
|
||||
html: true,
|
||||
offset: 1
|
||||
});
|
||||
},1000);
|
||||
});
|
BIN
accounts/public/favicon.ico
Executable file
After Width: | Height: | Size: 1.1 KiB |
91
accounts/public/index.html
Executable file
@ -0,0 +1,91 @@
|
||||
<!doctype html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta charSet='utf-8' />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<meta name="slack-app-id" content="ACVBMTPJQ">
|
||||
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
|
||||
<title>Fyipe Dashboard</title>
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/dashboard.css">
|
||||
<link rel="stylesheet" href="/assets/css/newdashboard.css">
|
||||
<link rel="stylesheet" href="/assets/css/sail.css">
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<link rel="stylesheet" href="/assets/css/loader.css">
|
||||
<link rel="stylesheet" href="/assets/css/blockchart.css">
|
||||
<link rel="stylesheet" href="/assets/css/Selector.css">
|
||||
<link rel="stylesheet" href="/assets/css/tutorial.css">
|
||||
<link rel="stylesheet" href="/assets/css/reactwidgets.css">
|
||||
|
||||
|
||||
<!-- Preload light, regular, medium and bold, which are fonts that are used on home -->
|
||||
<link rel="preload" href="/assets/fonts/camphor/font1.woff2" as="font" type="font/woff2" crossorigin="">
|
||||
<link rel="preload" href="/assets/fonts/camphor/font2.woff2" as="font" type="font/woff2" crossorigin="">
|
||||
<link rel="preload" href="/assets/fonts/camphor/font3.woff2" as="font" type="font/woff2" crossorigin="">
|
||||
<link rel="preload" href="/assets/fonts/camphor/font4.woff2" as="font" type="font/woff2" crossorigin="">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tipsy/1.0.3/jquery.tipsy.min.js" type="text/javascript"></script>
|
||||
<style type="text/css">
|
||||
/* Camphor */
|
||||
|
||||
@font-face {
|
||||
font-family: 'Camphor';
|
||||
font-weight: 300;
|
||||
src: url('/assets/fonts/camphor/font1.woff2') format('woff2'),
|
||||
url('/assets/fonts/camphor/font1.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Camphor';
|
||||
font-weight: 500;
|
||||
src: url('/assets/fonts/camphor/font2.woff2') format('woff2'),
|
||||
url('/assets/fonts/camphor/font2.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Camphor';
|
||||
font-weight: 600;
|
||||
src: url('/assets/fonts/camphor/font3.woff2') format('woff2'),
|
||||
url('/assets/fonts/camphor/font3.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Camphor';
|
||||
font-weight: 400;
|
||||
src: url('/assets/fonts/camphor/font4.woff2') format('woff2'),
|
||||
url('/assets/fonts/camphor/font4.woff') format('woff');
|
||||
}
|
||||
</style>
|
||||
<!-- Google Tag Manager -->
|
||||
<script>(function (w, d, s, l, i) {
|
||||
w[l] = w[l] || []; w[l].push({
|
||||
'gtm.start':
|
||||
new Date().getTime(), event: 'gtm.js'
|
||||
}); var f = d.getElementsByTagName(s)[0],
|
||||
j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src =
|
||||
'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f);
|
||||
})(window, document, 'script', 'dataLayer', 'GTM-PKQD5WH');</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
</head>
|
||||
<body>
|
||||
<div id="root" class="db-DashboardRoot"></div>
|
||||
<script>
|
||||
!function () {
|
||||
if ('PerformanceLongTaskTiming' in window) {
|
||||
var g = window.__tti = { e: [] };
|
||||
g.o = new PerformanceObserver(function (l) { g.e = g.e.concat(l.getEntries()) });
|
||||
g.o.observe({ entryTypes: ['longtask'] })
|
||||
}
|
||||
}();
|
||||
</script>
|
||||
<!-- Google Tag Manager (noscript) -->
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKQD5WH" height="0" width="0"
|
||||
style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<!-- End Google Tag Manager (noscript) -->
|
||||
</body>
|
||||
</html>
|
15
accounts/public/manifest.json
Executable file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "Fyipe",
|
||||
"name": "Fyipe Dashboard",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
51
accounts/src/App.js
Executable file
@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import { Router, Route, Redirect, Switch } from 'react-router-dom';
|
||||
import { history, isServer } from './store';
|
||||
import { connect } from 'react-redux';
|
||||
import { allRoutes } from './routes';
|
||||
import NotFound from './components/404';
|
||||
import BackboneModals from './containers/BackboneModals';
|
||||
|
||||
import ReactGA from 'react-ga';
|
||||
|
||||
if (!isServer) {
|
||||
history.listen(location => {
|
||||
ReactGA.set({ page: location.pathname });
|
||||
ReactGA.pageview(location.pathname);
|
||||
});
|
||||
}
|
||||
|
||||
const App = () => (
|
||||
<div style={{ height: '100%' }}>
|
||||
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
{allRoutes.filter(route => route.visible).map((route, index) => {
|
||||
return (
|
||||
<Route
|
||||
exact={route.exact}
|
||||
path={route.path}
|
||||
key={index}
|
||||
component={(route.component)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
<Route
|
||||
path={'/:404_path'}
|
||||
key={'404'}
|
||||
component={NotFound}
|
||||
/>
|
||||
<Redirect to="/login" />
|
||||
</Switch>
|
||||
</Router>
|
||||
<BackboneModals />
|
||||
</div>
|
||||
);
|
||||
|
||||
App.displayName = 'App'
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return state.login;
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(App);
|
61
accounts/src/actions/changePassword.js
Executable file
@ -0,0 +1,61 @@
|
||||
import {
|
||||
postApi
|
||||
} from '../api';
|
||||
import * as types from '../constants/changePassword'
|
||||
import errors from '../errors'
|
||||
|
||||
|
||||
export function changePasswordRequest(promise) {
|
||||
return {
|
||||
type: types.CHANGEPASSWORD_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
}
|
||||
|
||||
export function changePasswordError(error) {
|
||||
return {
|
||||
type: types.CHANGEPASSWORD_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
|
||||
export function changePasswordSuccess(values) {
|
||||
|
||||
return {
|
||||
type: types.CHANGEPASSWORD_SUCCESS,
|
||||
payload: values
|
||||
};
|
||||
}
|
||||
|
||||
export const resetChangePassword = () => {
|
||||
return {
|
||||
type: types.RESET_CHANGEPASSWORD,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to register a user.
|
||||
export function changePassword(values) {
|
||||
return function (dispatch) {
|
||||
|
||||
var promise = postApi('user/reset-password', values);
|
||||
dispatch(changePasswordRequest(promise));
|
||||
|
||||
promise.then(function (response) {
|
||||
dispatch(changePasswordSuccess(response.data));
|
||||
}, function (error) {
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
error = error.message;
|
||||
}
|
||||
else{
|
||||
error = 'Network Error';
|
||||
}
|
||||
dispatch(changePasswordError(errors(error)));
|
||||
});
|
||||
|
||||
};
|
||||
}
|
84
accounts/src/actions/login.js
Executable file
@ -0,0 +1,84 @@
|
||||
|
||||
import {
|
||||
postApi
|
||||
} from '../api';
|
||||
import * as types from '../constants/login'
|
||||
import { User, DASHBOARD_URL, DOMAIN_URL } from '../config.js';
|
||||
import errors from '../errors'
|
||||
import { getQueryVar } from '../config'
|
||||
|
||||
import Cookies from 'universal-cookie';
|
||||
|
||||
// There are three possible states for our login
|
||||
// process and we need actions for each of them
|
||||
|
||||
export function loginRequest(promise) {
|
||||
return {
|
||||
type: types.LOGIN_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
}
|
||||
|
||||
export function loginError(error) {
|
||||
return {
|
||||
type: types.LOGIN_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
|
||||
export function loginSuccess(user) {
|
||||
if (user.redirect) return window.location = `${user.redirect}?accessToken=${user.tokens.jwtAccessToken}`;
|
||||
//save user session details.
|
||||
User.setUserId(user.id);
|
||||
User.setAccessToken(user.tokens.jwtAccessToken);
|
||||
User.setEmail(user.email);
|
||||
User.setName(user.name);
|
||||
User.setCardRegistered(user.cardRegistered);
|
||||
|
||||
//share localStorage with dashboard app
|
||||
const cookies = new Cookies();
|
||||
var userData = user;
|
||||
cookies.set('data', userData, { path: '/', maxAge: 30, domain: DOMAIN_URL });
|
||||
|
||||
window.location = DASHBOARD_URL
|
||||
return {
|
||||
type: types.LOGIN_SUCCESS,
|
||||
payload: user
|
||||
};
|
||||
}
|
||||
|
||||
export const resetLogin = () => {
|
||||
return {
|
||||
type: types.RESET_LOGIN,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to register a user.
|
||||
export function loginUser(values) {
|
||||
const initialUrl = User.initialUrl();
|
||||
const redirect = getQueryVar('redirectTo', initialUrl)
|
||||
values.redirect = redirect;
|
||||
return function (dispatch) {
|
||||
|
||||
var promise = postApi('user/login', values);
|
||||
dispatch(loginRequest(promise));
|
||||
|
||||
promise.then(function (user) {
|
||||
dispatch(loginSuccess(user.data));
|
||||
}, function (error) {
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
error = error.message;
|
||||
}
|
||||
else{
|
||||
error = 'Network Error';
|
||||
}
|
||||
dispatch(loginError(errors(error)));
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
}
|
16
accounts/src/actions/modal.js
Executable file
@ -0,0 +1,16 @@
|
||||
import * as types from '../constants/modal'
|
||||
|
||||
export const openModal = function(obj) {
|
||||
return {
|
||||
type: types.OPEN_MODAL,
|
||||
payload: obj
|
||||
};
|
||||
}
|
||||
export const closeModal = function(obj) {
|
||||
return {
|
||||
type: types.CLOSE_MODAL,
|
||||
payload: obj
|
||||
};
|
||||
}
|
||||
|
||||
|
174
accounts/src/actions/register.js
Executable file
@ -0,0 +1,174 @@
|
||||
import {
|
||||
postApi
|
||||
} from '../api';
|
||||
import * as types from '../constants/register'
|
||||
import errors from '../errors'
|
||||
// There are three possible states for our login
|
||||
// process and we need actions for each of them
|
||||
|
||||
|
||||
export function signupError(error) {
|
||||
return {
|
||||
type: types.SIGNUP_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
|
||||
export function saveUserState(values) {
|
||||
return {
|
||||
type: types.SAVE_USER_STATE,
|
||||
payload: values
|
||||
};
|
||||
}
|
||||
|
||||
export function saveCardState(values) {
|
||||
return {
|
||||
type: types.SAVE_CARD_STATE,
|
||||
payload: values
|
||||
};
|
||||
}
|
||||
|
||||
export function saveCompanyState(values) {
|
||||
return {
|
||||
type: types.SAVE_COMPANY_STATE,
|
||||
payload: values
|
||||
};
|
||||
}
|
||||
|
||||
export function signUpRequest(promise) {
|
||||
return {
|
||||
type: types.SIGNUP_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
}
|
||||
|
||||
export function signUpReset() {
|
||||
return {
|
||||
type: types.RESET_SIGNUP,
|
||||
};
|
||||
}
|
||||
|
||||
export function signupSuccess(user) {
|
||||
return {
|
||||
type: types.SIGNUP_SUCCESS,
|
||||
payload: user
|
||||
}
|
||||
}
|
||||
|
||||
export const resetSignup = () => {
|
||||
return {
|
||||
type: types.RESET_SIGNUP,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to register a user.
|
||||
export function signupUser(values) {
|
||||
return function (dispatch) {
|
||||
var promise = postApi('user/signup', values);
|
||||
dispatch(signUpRequest(promise));
|
||||
promise.then(function (user) {
|
||||
dispatch(signupSuccess(user.data));
|
||||
}, function (error) {
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
error = error.message;
|
||||
}
|
||||
else{
|
||||
error = 'Network Error';
|
||||
}
|
||||
dispatch(signupError(errors(error)));
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//np payload for inc and dec action creators.
|
||||
export const incrementStep = () => {
|
||||
return {
|
||||
type: types.SIGNUP_STEP_INC,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
//np payload for inc and dec action creators.
|
||||
export const skipCardStep = () => {
|
||||
return {
|
||||
type: types.SKIP_CARD_STEP,
|
||||
};
|
||||
};
|
||||
|
||||
export const decrementStep = () => {
|
||||
return {
|
||||
type: types.SIGNUP_STEP_DEC,
|
||||
};
|
||||
};
|
||||
|
||||
// There are three possible states for our login
|
||||
// process and we need actions for each of them
|
||||
|
||||
export function isUserInvitedRequest(promise) {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
}
|
||||
|
||||
export function isUserInvitedReset() {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
};
|
||||
}
|
||||
|
||||
export function isUserInvitedError(error) {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
|
||||
export function isUserInvitedSuccess(data) {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_SUCCESS,
|
||||
payload:data
|
||||
};
|
||||
}
|
||||
|
||||
export const resetIsUserInvited = () => {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to register a user.
|
||||
export function isUserInvited(values) {
|
||||
return function (dispatch) {
|
||||
var promise = postApi('user/isInvited', values);
|
||||
dispatch(isUserInvitedRequest(promise));
|
||||
promise.then(function (response) {
|
||||
dispatch(isUserInvitedSuccess(response.data));
|
||||
}, function (error) {
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
error = error.message;
|
||||
}
|
||||
else{
|
||||
error = 'Network Error';
|
||||
}
|
||||
dispatch(isUserInvitedError(errors(error)));
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
}
|
51
accounts/src/actions/resendToken.js
Executable file
@ -0,0 +1,51 @@
|
||||
import { postApi } from '../api';
|
||||
import * as types from '../constants/resendToken'
|
||||
import errors from '../errors'
|
||||
|
||||
export function resendTokenRequest(promise) {
|
||||
return {
|
||||
type: types.RESENDTOKEN_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
}
|
||||
|
||||
export function resendTokenError(error) {
|
||||
return {
|
||||
type: types.RESENDTOKEN_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
|
||||
export function resendTokenSuccess(data) {
|
||||
|
||||
return {
|
||||
type: types.RESENDTOKEN_SUCCESS,
|
||||
payload: data
|
||||
};
|
||||
}
|
||||
|
||||
export function resendToken(values) {
|
||||
return function(dispatch){
|
||||
|
||||
var promise = postApi('user/resend', values);
|
||||
dispatch(resendTokenRequest(promise));
|
||||
|
||||
promise.then(function(data){
|
||||
dispatch(resendTokenSuccess(data));
|
||||
}, function(error){
|
||||
if(error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if(error && error.data){
|
||||
error = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
error = error.message;
|
||||
}
|
||||
else{
|
||||
error = 'Network Error';
|
||||
}
|
||||
dispatch(resendTokenError(errors(error)));
|
||||
});
|
||||
|
||||
};
|
||||
}
|
60
accounts/src/actions/resetPassword.js
Executable file
@ -0,0 +1,60 @@
|
||||
import { postApi } from '../api';
|
||||
import * as types from '../constants/resetPassword'
|
||||
import errors from '../errors'
|
||||
|
||||
// There are three possible states for our resetPassword
|
||||
// process and we need actions for each of them
|
||||
|
||||
export function resetPasswordRequest(promise) {
|
||||
return {
|
||||
type: types.PASSWORDRESET_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
}
|
||||
|
||||
export function resetPasswordError(error) {
|
||||
return {
|
||||
type: types.PASSWORDRESET_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
|
||||
export function resetPasswordSuccess(data) {
|
||||
|
||||
return {
|
||||
type: types.PASSWORDRESET_SUCCESS,
|
||||
payload: data
|
||||
};
|
||||
}
|
||||
|
||||
export const resetResetPassword = () => {
|
||||
return {
|
||||
type: types.RESET_PASSWORDRESET,
|
||||
};
|
||||
};
|
||||
|
||||
export function resetPassword(values) {
|
||||
return function(dispatch){
|
||||
|
||||
var promise = postApi('user/forgot-password', values);
|
||||
dispatch(resetPasswordRequest(promise));
|
||||
|
||||
promise.then(function(data){
|
||||
dispatch(resetPasswordSuccess(data));
|
||||
}, function(error){
|
||||
if(error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if(error && error.data){
|
||||
error = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
error = error.message;
|
||||
}
|
||||
else{
|
||||
error = 'Network Error';
|
||||
}
|
||||
dispatch(resetPasswordError(errors(error)));
|
||||
});
|
||||
|
||||
};
|
||||
}
|
135
accounts/src/api.js
Executable file
@ -0,0 +1,135 @@
|
||||
import axios from 'axios';
|
||||
import {
|
||||
API_URL
|
||||
} from './config';
|
||||
import {
|
||||
User
|
||||
} from './config';
|
||||
import { history } from './store';
|
||||
var baseURL = API_URL;
|
||||
|
||||
var Q = require('q');
|
||||
|
||||
var headers = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
};
|
||||
|
||||
|
||||
|
||||
export function postApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
var deffered = Q.defer();
|
||||
|
||||
axios({
|
||||
method: 'POST',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
})
|
||||
.then(function (response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
}
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
}
|
||||
deffered.reject(error);
|
||||
});
|
||||
return deffered.promise;
|
||||
}
|
||||
|
||||
export function getApi(url) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
var deffered = Q.defer();
|
||||
axios({
|
||||
method: 'GET',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers
|
||||
})
|
||||
.then(function (response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
}
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
}
|
||||
deffered.reject(error);
|
||||
});
|
||||
|
||||
return deffered.promise;
|
||||
}
|
||||
|
||||
|
||||
export function putApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
var deffered = Q.defer();
|
||||
axios({
|
||||
method: 'PUT',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
})
|
||||
.then(function (response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
}
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
}
|
||||
deffered.reject(error);
|
||||
});
|
||||
|
||||
return deffered.promise;
|
||||
}
|
||||
|
||||
export function deleteApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
var deffered = Q.defer();
|
||||
axios({
|
||||
method: 'DELETE',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
})
|
||||
.then(function (response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
}
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
}
|
||||
deffered.reject(error);
|
||||
});
|
||||
|
||||
return deffered.promise;
|
||||
}
|
35
accounts/src/components/404.js
Executable file
@ -0,0 +1,35 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
|
||||
class NotFound extends Component {
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
<div className="db-World-root" >
|
||||
|
||||
<div className="db-World-wrapper Box-root Flex-flex Flex-direction--column">
|
||||
|
||||
|
||||
<div>
|
||||
|
||||
<div id="app-loading" style={{ 'position': 'fixed', 'top': '0', 'bottom': '0', 'left': '0', 'right': '0', 'zIndex': '1', 'display': 'flex', 'justifyContent': 'center', 'alignItems': 'center', 'fontSize': '20px', 'flexDirection': 'column' }}>
|
||||
<div>The page you requested does not exist.</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
NotFound.displayName = 'NotFound'
|
||||
|
||||
|
||||
export default NotFound;
|
27
accounts/src/components/MessageBox.js
Executable file
@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default function MessageBox(props) {
|
||||
return (
|
||||
<div id="main-body" className="box css">
|
||||
<div className="inner">
|
||||
<div className="request-reset-step step" >
|
||||
<div className="title">
|
||||
<h2>
|
||||
{props.title}
|
||||
</h2>
|
||||
</div>
|
||||
<p className="error-message hidden" />
|
||||
<p className="message">{props.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
MessageBox.displayName = 'MessageBox'
|
||||
|
||||
MessageBox.propTypes = {
|
||||
title: PropTypes.string,
|
||||
message: PropTypes.string,
|
||||
}
|
76
accounts/src/components/Modal.js
Executable file
@ -0,0 +1,76 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
const composableComponent = (ComposedComponent) => {
|
||||
class Modal extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.onClose = this.onClose.bind(this);
|
||||
this.onConfirm = this.onConfirm.bind(this);
|
||||
}
|
||||
onClose =(value)=> {
|
||||
if (this.props.item.onClose) {
|
||||
this.props.item.onClose(value);
|
||||
this.props.onClose(this.props.item);
|
||||
} else {
|
||||
this.props.onClose(this.props.item);
|
||||
}
|
||||
}
|
||||
onConfirm = (value)=> {
|
||||
var _this = this;
|
||||
if (this.props.item.onConfirm) {
|
||||
this.props.item.onConfirm(value)
|
||||
.then(() => _this.props.onClose(_this.props.item),
|
||||
()=> {})
|
||||
} else {
|
||||
this.props.onClose(this.props.item)
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const { zIndex } = this.props;
|
||||
const { extraClasses } = this.props.item;
|
||||
|
||||
const mainClass = `${extraClasses || ''} modal-dialog-view`;
|
||||
const modalContainerStyle = {overflowX: 'auto', overflowY: 'scroll', display: 'block', top: '0px'};
|
||||
return (
|
||||
<div
|
||||
className={mainClass}
|
||||
style={{
|
||||
zIndex: (zIndex + 1) * 10000
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="modal_overlay"
|
||||
style={{
|
||||
top: 0,
|
||||
opacity: 1,
|
||||
transform: 'none',
|
||||
display: 'block',
|
||||
pointerEvents: 'auto'
|
||||
}}
|
||||
>
|
||||
|
||||
<div className="modal_container" style={modalContainerStyle}>
|
||||
<ComposedComponent closeThisDialog={this.onClose} confirmThisDialog={this.onConfirm} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
Modal.propTypes = {
|
||||
onConfirm: PropTypes.func,
|
||||
item: PropTypes.object.isRequired,
|
||||
onClose:PropTypes.func.isRequired,
|
||||
extraClasses: PropTypes.string,
|
||||
zIndex: PropTypes.number.isRequired
|
||||
}
|
||||
|
||||
Modal.displayName = 'Modal'
|
||||
|
||||
return Modal;
|
||||
}
|
||||
|
||||
|
||||
export default composableComponent;
|
258
accounts/src/components/auth/CardForm.js
Executable file
@ -0,0 +1,258 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import RenderCountrySelector from '../basic/CountrySelector';
|
||||
import { connect } from 'react-redux';
|
||||
import { RenderField } from '../basic/RenderField'
|
||||
import { PricingPlan } from '../../config';
|
||||
import { Validate } from '../../config';
|
||||
import { FlatLoader } from '../basic/Loader.js';
|
||||
|
||||
class CardForm extends Component {
|
||||
|
||||
render() {
|
||||
this.plan = PricingPlan.getPlanById(this.props.planId);
|
||||
|
||||
return (
|
||||
<div id="main-body" className="box css">
|
||||
<div className="inner">
|
||||
<div className="title extra">
|
||||
<div>
|
||||
<h2>
|
||||
<span> {this.props.register.error ? <span className="error" >{this.props.register.error}</span> : 'Enter your card details'}
|
||||
</span>
|
||||
</h2>
|
||||
<p>Your card will be charged $1.00 to check its billability. You will be charged ${this.plan.amount}/{this.plan.type === 'month' ? 'mo' : 'yr'} after your 14 day free trial.</p>
|
||||
</div>
|
||||
</div>
|
||||
<form id="card-form" onSubmit={this.props.handleSubmit(this.props.submitForm)}>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="cardName">Card Holder Name</label>
|
||||
<Field
|
||||
type="text"
|
||||
name="cardName"
|
||||
id="cardName"
|
||||
placeholder="Card Holder Name"
|
||||
component={RenderField}
|
||||
required="required"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="cardNumber">Card Number</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="cardNumber"
|
||||
id="cardNumber"
|
||||
placeholder="1234 4534 2322 1234"
|
||||
required="required"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="cvv">CVV</label>
|
||||
<Field
|
||||
type="password"
|
||||
component={RenderField}
|
||||
name="cvc"
|
||||
id="cvv"
|
||||
placeholder="CVV"
|
||||
required="required"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="expiry">Expiry Date</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="expiry"
|
||||
id="expiry"
|
||||
placeholder="01/2019"
|
||||
required="required"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="address1">Street Address 1</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="address1"
|
||||
id="address1"
|
||||
placeholder="Street Address 1"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="address2">Street Address 2</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="address2"
|
||||
id="address2"
|
||||
placeholder="Street Address 2"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="city">City</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="city"
|
||||
id="city"
|
||||
placeholder="City"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="state">State</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="state"
|
||||
id="state"
|
||||
placeholder="State (Optional)"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="zipCode">Zip Code / Postal Code</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="zipCode"
|
||||
id="zipCode"
|
||||
placeholder="Zip Code or Postal Code"
|
||||
required="required"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="country">Country</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderCountrySelector}
|
||||
name="country"
|
||||
id="country"
|
||||
placeholder="Select Country"
|
||||
required="required"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="promocode">Promo Code(optional)</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="promocode"
|
||||
id="promocode"
|
||||
placeholder="Promocode (Optional)"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<div>
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" id="create-account-button" disabled={this.props.register.requesting}>
|
||||
{!this.props.register.requesting && <span>Create Fyipe Account</span>}
|
||||
{this.props.register.requesting && <FlatLoader />}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CardForm.displayName = 'CardForm'
|
||||
|
||||
let validate = function (values) {
|
||||
const errors = {};
|
||||
|
||||
if (!Validate.text(values.cardName)) {
|
||||
errors.cardName = 'Name is required.'
|
||||
}
|
||||
if (!Validate.text(values.cardNumber)) {
|
||||
errors.cardNumber = 'Card Number is required'
|
||||
}
|
||||
if (!Validate.text(values.cvc)) {
|
||||
errors.cvc = 'CVV is required.'
|
||||
}
|
||||
if (!Validate.text(values.expiry)) {
|
||||
errors.expiry = 'Expiry date is required.'
|
||||
}
|
||||
|
||||
if (!Validate.text(values.city)) {
|
||||
errors.city = 'City is required.'
|
||||
}
|
||||
|
||||
if (!Validate.text(values.zipCode)) {
|
||||
errors.zipCode = 'Zip Code or Postal Code is required.'
|
||||
}
|
||||
|
||||
if (!Validate.text(values.country)) {
|
||||
errors.country = 'Country is required.';
|
||||
}
|
||||
|
||||
if (!Validate.card(values.cardNumber)) {
|
||||
errors.cardNumber = 'Incorrect card number.';
|
||||
}
|
||||
|
||||
if (!Validate.cardExpiration(values.expiry)) {
|
||||
errors.expiry = 'Expiration date is invalid.';
|
||||
}
|
||||
|
||||
if (!Validate.cvv(values.cvc)) {
|
||||
errors.cvc = 'CVV is invalid.';
|
||||
}
|
||||
|
||||
if (!Validate.postalCode(values.zipCode)) {
|
||||
errors.zipCode = 'Postal Code or Zip Code is invalid.';
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
|
||||
let cardForm = reduxForm({
|
||||
form: 'CardForm', // <------ same form name // <----- validate form data
|
||||
destroyOnUnmount: false, // <------ preserve form data
|
||||
forceUnregisterOnUnmount: true, // <------ unregister fields on unmount
|
||||
validate
|
||||
})(CardForm);
|
||||
|
||||
const mapDispatchToProps = (dispatch_Ignored) => {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
register: state.register
|
||||
};
|
||||
}
|
||||
|
||||
CardForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
submitForm: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
planId: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(cardForm);
|
117
accounts/src/components/auth/ChangePasswordForm.js
Executable file
@ -0,0 +1,117 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { Validate } from '../../config';
|
||||
import { FlatLoader } from '../basic/Loader.js';
|
||||
import { changePasswordError, changePasswordSuccess, changePassword, resetChangePassword } from '../../actions/changePassword';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { RenderField } from '../basic/RenderField';
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
export class ChangePasswordForm extends Component {
|
||||
|
||||
submitForm =(values)=> {
|
||||
values.token = this.props.token || '';
|
||||
this.props.changePassword(values);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="main-body" className="box css">
|
||||
<div className="inner">
|
||||
<form onSubmit={this.props.handleSubmit(this.submitForm)} className="request-reset">
|
||||
<div className="request-reset-step step" >
|
||||
<div className="title">
|
||||
<h2>
|
||||
<span > {this.props.changePasswordState.error ? <span className="error" >{this.props.changePasswordState.error}</span> : 'Reset Password'} </span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<p className="error-message hidden" />
|
||||
|
||||
|
||||
{this.props.changePasswordState.success && <p className="message"> Your password is changed. Please <Link to="/login"> click here to login </Link> </p>}
|
||||
{!this.props.changePasswordState.success && <p className="message"> Enter your email address below and we will send you a link to
|
||||
reset your password. </p>}
|
||||
|
||||
|
||||
{!this.props.changePasswordState.success && <div> <p className="text">
|
||||
<span>
|
||||
<label htmlFor="password"> Password </label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="password"
|
||||
name="password"
|
||||
id="password"
|
||||
placeholder="Password"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="confirmPassword"> Confirm Password </label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="password"
|
||||
name="confirmPassword"
|
||||
id="confirmPassword"
|
||||
placeholder="Confirm Password"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" disabled={this.props.changePasswordState.requesting}>
|
||||
{!this.props.changePasswordState.requesting && <span>Change Password</span>}
|
||||
{this.props.changePasswordState.requesting && <FlatLoader />}
|
||||
</button>
|
||||
</p> </div>}
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ChangePasswordForm.displayName = 'ChangePasswordForm'
|
||||
|
||||
function validate(values) {
|
||||
let errors = {};
|
||||
if (!Validate.text(values.password)) {
|
||||
errors.password = 'Password is required.'
|
||||
}
|
||||
if (!Validate.text(values.confirmPassword)) {
|
||||
errors.confirmPassword = 'Confirm Password is invalid.'
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
let changePasswordForm = reduxForm({
|
||||
form: 'changePasswordForm', // a unique identifier for this form
|
||||
validate
|
||||
})(ChangePasswordForm);
|
||||
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
changePasswordError, changePasswordSuccess, changePassword, resetChangePassword
|
||||
}, dispatch);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
changePasswordState: state.changePassword
|
||||
};
|
||||
}
|
||||
|
||||
ChangePasswordForm.propTypes = {
|
||||
changePassword: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
changePasswordState: PropTypes.object.isRequired,
|
||||
token: PropTypes.any
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(changePasswordForm);
|
182
accounts/src/components/auth/CompanyForm.js
Executable file
@ -0,0 +1,182 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import CountrySelector from '../basic/CountrySelector';
|
||||
import CompanySizeSelector from '../basic/CompanySizeSelector';
|
||||
import { connect } from 'react-redux';
|
||||
import {RenderField} from '../basic/RenderField'
|
||||
import {Validate} from '../../config';
|
||||
import {FlatLoader} from '../basic/Loader.js';
|
||||
|
||||
|
||||
let errorStyle = {
|
||||
color:'red'
|
||||
}
|
||||
|
||||
class CompanyForm extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="main-body" className="box css">
|
||||
<div className="inner">
|
||||
<div className="title extra">
|
||||
|
||||
<h2><span> {this.props.register.error ? <span style={errorStyle} > {this.props.register.error}</span> : 'One Last Step...'} </span></h2>
|
||||
</div>
|
||||
<form onSubmit={this.props.handleSubmit(this.props.submitForm)}>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="companyName">Company Name</label>
|
||||
<Field
|
||||
type="text"
|
||||
name="companyName"
|
||||
id="companyName"
|
||||
component={RenderField}
|
||||
placeholder="Company Name"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="companyRole">Job Title</label>
|
||||
<Field
|
||||
type="text"
|
||||
name="companyRole"
|
||||
id="companyRole"
|
||||
component={RenderField}
|
||||
placeholder="Your Job Title"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="companyCountry">Country</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={CountrySelector}
|
||||
name="companyCountry"
|
||||
id="companyCountry"
|
||||
placeholder="Company Country"
|
||||
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="companySize">Company Size</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={CompanySizeSelector}
|
||||
name="companySize"
|
||||
id="companySize"
|
||||
placeholder="company Size"
|
||||
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="companyPhoneNumber">Phone Number</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="companyPhoneNumber"
|
||||
id="companyPhoneNumber"
|
||||
placeholder="+1-123-456-7890"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="reference">Where did you hear about us?</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="reference"
|
||||
id="reference"
|
||||
placeholder="e.g Facebook"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="reference">Promo Code(optional)</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="promocode"
|
||||
id="promocode"
|
||||
placeholder="Promocode (Optional)"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<div>
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" id="create-account-button" disabled={this.props.register.requesting}>
|
||||
{ !this.props.register.requesting && <span>Create Fyipe Account</span> }
|
||||
{ this.props.register.requesting && <FlatLoader /> }
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CompanyForm.displayName = 'CompanyForm'
|
||||
|
||||
let validate = function(values){
|
||||
let error = {};
|
||||
|
||||
if(!Validate.text(values.companyName)){
|
||||
error.companyName = 'Company name is required.'
|
||||
}
|
||||
|
||||
if(!Validate.text(values.companyRole)){
|
||||
error.companyRole = 'Job Title is required.'
|
||||
}
|
||||
|
||||
if(!Validate.text(values.companyPhoneNumber)){
|
||||
error.companyPhoneNumber ='Phone Number is required.'
|
||||
}
|
||||
|
||||
if(!Validate.text(values.comapnySize)){
|
||||
error.comapnySize ='Phone Number is required.'
|
||||
}
|
||||
|
||||
if(!Validate.text(values.reference)){
|
||||
error.reference ='This is required.'
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
let companyForm = reduxForm({
|
||||
form: 'CompanyForm', // <------ same form name
|
||||
destroyOnUnmount: false, // <------ preserve form data
|
||||
forceUnregisterOnUnmount: true,
|
||||
validate // <------ unregister fields on unmoun
|
||||
})(CompanyForm);
|
||||
|
||||
const mapDispatchToProps = (dispatch_Ignored) => {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
register: state.register
|
||||
};
|
||||
}
|
||||
|
||||
CompanyForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
submitForm: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(companyForm);
|
146
accounts/src/components/auth/LoginForm.js
Executable file
@ -0,0 +1,146 @@
|
||||
import React, { Component } from 'react'
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { RenderField } from '../basic/RenderField';
|
||||
import { connect } from 'react-redux';
|
||||
import { Validate } from '../../config';
|
||||
import { FlatLoader } from '../basic/Loader.js';
|
||||
import { loginError, loginSuccess, loginUser, resetLogin } from '../../actions/login';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import queryString from 'query-string';
|
||||
import { removeQuery } from '../../store';
|
||||
|
||||
export class LoginForm extends Component {
|
||||
|
||||
state = {
|
||||
serverResponse: ''
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const query = queryString.parse(this.props.location.search).status;
|
||||
var serverResponse = '';
|
||||
if (query === 'IIYQNdn4impaXQeeteTBEBmz0If1rlwC') {
|
||||
serverResponse = 'Email already verified. You can now login.'
|
||||
}
|
||||
else if (query === 'V0JvLGX4U0lgO9Z9ulrOXFW9pNSGLSnP') {
|
||||
serverResponse = 'Thank you for verifying your email. You can now login.'
|
||||
}
|
||||
this.setState({
|
||||
serverResponse
|
||||
});
|
||||
removeQuery('status');
|
||||
}
|
||||
render() {
|
||||
const { handleSubmit } = this.props;
|
||||
const { serverResponse } = this.state;
|
||||
|
||||
return (
|
||||
<div id="main-body" className="box css">
|
||||
<div className="inner login">
|
||||
<div>
|
||||
<form onSubmit={handleSubmit(this.props.onSubmit)}>
|
||||
<div className="step email-password-step">
|
||||
<h2>
|
||||
{serverResponse ? (<span>{serverResponse}</span>) :
|
||||
(<span > {this.props.login.error ? <span className="error" >{this.props.login.error}</span> : 'Welcome back!'} </span>
|
||||
)}
|
||||
</h2>
|
||||
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="email">
|
||||
<span>Email</span>
|
||||
</label>
|
||||
<Field className="error"
|
||||
component={RenderField}
|
||||
type="email"
|
||||
name="email"
|
||||
id="email"
|
||||
placeholder="jeff@example.com"
|
||||
required="required"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="password">
|
||||
<span>Password</span>
|
||||
</label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="password"
|
||||
name="password"
|
||||
id="password"
|
||||
placeholder="Your Password"
|
||||
required="required"
|
||||
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" id="login-button" disabled={this.props.login.requesting}>
|
||||
{!this.props.login.requesting && <span>Sign in to your account</span>}
|
||||
{this.props.login.requesting && <FlatLoader />}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
LoginForm.displayName = 'LoginForm'
|
||||
|
||||
let validate = function (values) {
|
||||
const errors = {};
|
||||
if (!Validate.text(values.email)) {
|
||||
errors.email = 'Email is required.'
|
||||
}
|
||||
|
||||
else {
|
||||
if (!Validate.email(values.email)) {
|
||||
errors.email = 'Email is invalid.'
|
||||
}
|
||||
}
|
||||
|
||||
if (!Validate.text(values.password)) {
|
||||
errors.password = 'Password is required.'
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
let loginForm = reduxForm({
|
||||
form: 'LoginForm', // a unique identifier for this form
|
||||
validate,
|
||||
destroyOnUnmount: false
|
||||
})(LoginForm);
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
loginError, loginSuccess, loginUser, resetLogin
|
||||
}, dispatch);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
login: state.login
|
||||
};
|
||||
}
|
||||
|
||||
LoginForm.contextTypes = {
|
||||
mixpanel: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
LoginForm.propTypes = {
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
login: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(loginForm);
|
117
accounts/src/components/auth/RegisterForm.js
Executable file
@ -0,0 +1,117 @@
|
||||
import React, { Component } from 'react'
|
||||
import { reduxForm } from 'redux-form'
|
||||
import UserForm from './UserForm';
|
||||
import CardForm from './CardForm';
|
||||
import { connect } from 'react-redux';
|
||||
import { signupError, signupSuccess, signupUser, incrementStep, decrementStep, resetSignup, saveUserState, saveCardState, isUserInvited } from '../../actions/register'
|
||||
import { bindActionCreators } from 'redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export class RegisterForm extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
userFormSubmitted = (values) => {
|
||||
let thisObj = this;
|
||||
this.props.saveUserState(values);
|
||||
this.props.isUserInvited(values).then(function (value) {
|
||||
if (value.data) {
|
||||
thisObj.props.signupUser({...values, planId: thisObj.props.planId })
|
||||
.then((user) => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if (window.location.href.indexOf('localhost') <= -1) {
|
||||
thisObj.context.mixpanel.identify(user.data.id);
|
||||
thisObj.context.mixpanel.people.set({
|
||||
'$first_name': user.data.name,
|
||||
'$created': new Date(),
|
||||
'$email': user.data.email
|
||||
});
|
||||
thisObj.context.mixpanel.track('user registered', { 'First Time': 'TRUE', 'id': user.data.id });
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
thisObj.props.incrementStep();
|
||||
}
|
||||
}, function (error) {
|
||||
return error
|
||||
});
|
||||
}
|
||||
|
||||
cardFormSubmitted = (values) => {
|
||||
var thisObj = this;
|
||||
this.props.saveCardState(values);
|
||||
this.props.signupUser({ ...this.props.register.user, ...values, planId: this.props.planId })
|
||||
.then((user) => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if (window.location.href.indexOf('localhost') <= -1) {
|
||||
thisObj.context.mixpanel.identify(user.data.id);
|
||||
thisObj.context.mixpanel.people.set({
|
||||
'$first_name': user.data.name,
|
||||
'$created': new Date(),
|
||||
'$email': user.data.email
|
||||
});
|
||||
thisObj.context.mixpanel.track('user registered', { 'First Time': 'TRUE', 'id': user.data.id });
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
{this.props.register.step === 1 && <UserForm submitForm={this.userFormSubmitted} error={this.props.register.error} location={this.props.location} />}
|
||||
{this.props.register.step === 2 && <CardForm planId={this.props.planId} submitForm={this.cardFormSubmitted} error={this.props.register.error} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RegisterForm.displayName = 'RegisterForm'
|
||||
|
||||
let registerForm = reduxForm({
|
||||
form: 'RegisterForm'
|
||||
})(RegisterForm);
|
||||
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
signupError,
|
||||
signupSuccess,
|
||||
signupUser,
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
resetSignup,
|
||||
saveUserState,
|
||||
saveCardState,
|
||||
isUserInvited,
|
||||
}, dispatch);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
register: state.register
|
||||
};
|
||||
}
|
||||
|
||||
RegisterForm.contextTypes = {
|
||||
mixpanel: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
RegisterForm.propTypes = {
|
||||
signupUser: PropTypes.func.isRequired,
|
||||
saveCardState: PropTypes.func.isRequired,
|
||||
//incrementStep: PropTypes.func.isRequired,
|
||||
saveUserState: PropTypes.func.isRequired,
|
||||
isUserInvited: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
planId: PropTypes.string.isRequired,
|
||||
location: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(registerForm);
|
104
accounts/src/components/auth/ResetPasswordForm.js
Executable file
@ -0,0 +1,104 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { Validate } from '../../config';
|
||||
import { FlatLoader } from '../basic/Loader.js';
|
||||
import { resetPasswordError, resetPasswordSuccess, resetPassword, resetResetPassword } from '../../actions/resetPassword';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { RenderField } from '../basic/RenderField';
|
||||
|
||||
export class ResetPasswordForm extends Component {
|
||||
|
||||
submitForm = (values) => {
|
||||
this.props.resetPassword(values);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div id="main-body" className="box css">
|
||||
<div className="inner">
|
||||
<form onSubmit={this.props.handleSubmit(this.submitForm)} className="request-reset">
|
||||
<div className="request-reset-step step" >
|
||||
<div className="title">
|
||||
<h2>
|
||||
<span > {this.props.resetPasswordState.error ? <span id="error-msg" className="error" >{this.props.resetPasswordState.error}</span> : 'Reset Password'} </span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<p className="error-message hidden" />
|
||||
|
||||
|
||||
{this.props.resetPasswordState.success && <p id="reset-password-success" className="message"> An email is on its way to you. Follow the instructions to
|
||||
reset your password. Please don't forget to check spam. </p>}
|
||||
{!this.props.resetPasswordState.success && <p className="message"> Enter your email address below and we will send you a link to
|
||||
reset your password. </p>}
|
||||
|
||||
|
||||
{!this.props.resetPasswordState.success && <div> <p className="text">
|
||||
<span>
|
||||
<label htmlFor="email"> Your Email</label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="email"
|
||||
name="email"
|
||||
id="email"
|
||||
placeholder="Your Email"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" disabled={this.props.resetPasswordState.requesting}>
|
||||
{!this.props.resetPasswordState.requesting && <span>Reset Password</span>}
|
||||
{this.props.resetPasswordState.requesting && <FlatLoader />}
|
||||
</button>
|
||||
</p> </div>}
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ResetPasswordForm.displayName = 'ResetPasswordForm'
|
||||
|
||||
function validate(values) {
|
||||
let errors = {};
|
||||
if (!Validate.text(values.email)) {
|
||||
errors.email = 'Email is required.'
|
||||
}
|
||||
else if (!Validate.email(values.email)) {
|
||||
errors.email = 'Email is invalid.'
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
let resetPasswordForm = reduxForm({
|
||||
form: 'resetPasswordForm', // a unique identifier for this form
|
||||
validate
|
||||
})(ResetPasswordForm);
|
||||
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
resetPasswordError, resetPasswordSuccess, resetPassword, resetResetPassword
|
||||
}, dispatch);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
resetPasswordState: state.resetPassword
|
||||
};
|
||||
}
|
||||
|
||||
ResetPasswordForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
resetPasswordState: PropTypes.object.isRequired,
|
||||
resetPassword: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(resetPasswordForm);
|
203
accounts/src/components/auth/UserForm.js
Executable file
@ -0,0 +1,203 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { Validate } from '../../config';
|
||||
import { RenderField } from '../basic/RenderField';
|
||||
import { FlatLoader } from '../basic/Loader.js';
|
||||
import { removeQuery } from '../../store';
|
||||
import queryString from 'query-string';
|
||||
|
||||
class UserForm extends Component {
|
||||
|
||||
state = {
|
||||
serverResponse: ''
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
var query = queryString.parse(this.props.location.search).status;
|
||||
if (query === 'z1hb0g8vfg0rWM1Ly1euQSZ1L5ZNHuAk') {
|
||||
this.setState({
|
||||
serverResponse: 'No user found for this token'
|
||||
});
|
||||
}
|
||||
removeQuery();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { serverResponse } = this.state;
|
||||
return (
|
||||
<div id="main-body" className="box css">
|
||||
<div className="inner">
|
||||
<div className="title extra">
|
||||
<h2>
|
||||
{
|
||||
serverResponse ? <span>{serverResponse}</span> :
|
||||
<span> {this.props.register.error ? <span id="error-msg" className="error" >{this.props.register.error}</span> : 'Create your Fyipe account.'} </span>
|
||||
}
|
||||
</h2>
|
||||
</div>
|
||||
<form onSubmit={this.props.handleSubmit(this.props.submitForm)}>
|
||||
|
||||
<p className="text">
|
||||
<span id="ema">
|
||||
<label htmlFor="email">Email</label>
|
||||
<Field
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
component={RenderField}
|
||||
placeholder="jeff@example.com"
|
||||
required="required"
|
||||
value={this.props.register.user.email || ''}
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="name">Full Name</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="name"
|
||||
id="name"
|
||||
placeholder="Jeff Smith"
|
||||
required="required"
|
||||
value={this.props.register.user.name || ''}
|
||||
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="companyName">Company Name</label>
|
||||
<Field
|
||||
type="text"
|
||||
name="companyName"
|
||||
id="companyName"
|
||||
component={RenderField}
|
||||
placeholder="Company Name"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="companyPhoneNumber">Phone Number</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="companyPhoneNumber"
|
||||
id="companyPhoneNumber"
|
||||
placeholder="+1-123-456-7890"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="password">Password</label>
|
||||
<Field
|
||||
type="password"
|
||||
component={RenderField}
|
||||
name="password"
|
||||
id="password"
|
||||
placeholder="Your Password"
|
||||
className="password-strength-input"
|
||||
required="required"
|
||||
value={this.props.register.user.password || ''}
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="confirmPassword">Confirm Password</label>
|
||||
<Field
|
||||
type="password"
|
||||
component={RenderField}
|
||||
name="confirmPassword"
|
||||
id="confirmPassword"
|
||||
placeholder="Confirm Password"
|
||||
required="required"
|
||||
value={this.props.register.user.confirmPassword || ''}
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<div>
|
||||
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" id="create-account-button" disabled={this.props.register && ((this.props.register.isUserInvited && this.props.register.isUserInvited.requesting) || this.props.register.requesting )}>
|
||||
{this.props.register && ((this.props.register.isUserInvited && this.props.register.isUserInvited.requesting) || this.props.register.requesting ) ? <FlatLoader /> : <span>Create Fyipe Account</span>}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UserForm.displayName = 'UserForm'
|
||||
|
||||
let validate = function (values) {
|
||||
let error = {};
|
||||
|
||||
if (!Validate.text(values.name))
|
||||
error.name = 'Name is required.';
|
||||
|
||||
if (!Validate.text(values.email))
|
||||
error.email = 'Email is required.';
|
||||
|
||||
if (Validate.text(values.email) && !Validate.email(values.email))
|
||||
error.email = 'Email is not valid.';
|
||||
|
||||
if (!Validate.isValidBusinessEmail(values.email) && Validate.email(values.email))
|
||||
error.email = 'Please enter a business email address.';
|
||||
|
||||
if (!Validate.text(values.companyName))
|
||||
error.companyName = 'Company name is required.';
|
||||
|
||||
if (!Validate.text(values.companyPhoneNumber))
|
||||
error.companyPhoneNumber = 'Phone number is required.';
|
||||
|
||||
if (!Validate.text(values.password))
|
||||
error.password = 'Password is required.';
|
||||
|
||||
if (!Validate.text(values.confirmPassword))
|
||||
error.confirmPassword = 'Confirm Password is required.';
|
||||
|
||||
if (!Validate.compare(values.password, values.confirmPassword)) {
|
||||
error.confirmPassword = 'Password and confirm password should match.';
|
||||
}
|
||||
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
let userForm = reduxForm({
|
||||
form: 'UserSignupForm', // <------ same form name
|
||||
destroyOnUnmount: false,
|
||||
validate
|
||||
})(UserForm);
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
|
||||
}, dispatch);
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
register: state.register
|
||||
};
|
||||
}
|
||||
|
||||
UserForm.propTypes = {
|
||||
submitForm: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(userForm);
|
7
accounts/src/components/basic/CompanySizeList.js
Executable file
@ -0,0 +1,7 @@
|
||||
export const companySize = [
|
||||
{ name: '1-10', code: '1-10' },
|
||||
{ name: '11-50', code: '11-50' },
|
||||
{ name: '51-200', code: '51-200' },
|
||||
{ name: '200-1000', code: '200-1000' },
|
||||
{ name: '1000+', code: '1000+' }
|
||||
];
|
32
accounts/src/components/basic/CompanySizeSelector.js
Executable file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { companySize } from './CompanySizeList';
|
||||
|
||||
let errorStyle = {
|
||||
color: 'red',
|
||||
topMargin: '5px'
|
||||
}
|
||||
|
||||
const CompanySizeSelector = ({ input, id, meta: { touched, error } }) => (
|
||||
<span>
|
||||
<select {...input} className="selector" id={id}>
|
||||
<option value="">Select Company Size...</option>
|
||||
{companySize.map(val => (
|
||||
<option value={val.name} key={val.code}>
|
||||
{val.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{touched && error && <span style={errorStyle}>{error}</span>}
|
||||
</span>
|
||||
)
|
||||
|
||||
CompanySizeSelector.displayName = 'CompanySizeSelector'
|
||||
|
||||
CompanySizeSelector.propTypes = {
|
||||
meta: PropTypes.object.isRequired,
|
||||
input: PropTypes.object.isRequired,
|
||||
id: PropTypes.string
|
||||
}
|
||||
|
||||
export default CompanySizeSelector
|
245
accounts/src/components/basic/CountryList.js
Executable file
@ -0,0 +1,245 @@
|
||||
export const countries = [
|
||||
{ name: 'Afghanistan', code: 'AF' },
|
||||
{ name: 'Åland Islands', code: 'AX' },
|
||||
{ name: 'Albania', code: 'AL' },
|
||||
{ name: 'Algeria', code: 'DZ' },
|
||||
{ name: 'American Samoa', code: 'AS' },
|
||||
{ name: 'AndorrA', code: 'AD' },
|
||||
{ name: 'Angola', code: 'AO' },
|
||||
{ name: 'Anguilla', code: 'AI' },
|
||||
{ name: 'Antarctica', code: 'AQ' },
|
||||
{ name: 'Antigua and Barbuda', code: 'AG' },
|
||||
{ name: 'Argentina', code: 'AR' },
|
||||
{ name: 'Armenia', code: 'AM' },
|
||||
{ name: 'Aruba', code: 'AW' },
|
||||
{ name: 'Australia', code: 'AU' },
|
||||
{ name: 'Austria', code: 'AT' },
|
||||
{ name: 'Azerbaijan', code: 'AZ' },
|
||||
{ name: 'Bahamas', code: 'BS' },
|
||||
{ name: 'Bahrain', code: 'BH' },
|
||||
{ name: 'Bangladesh', code: 'BD' },
|
||||
{ name: 'Barbados', code: 'BB' },
|
||||
{ name: 'Belarus', code: 'BY' },
|
||||
{ name: 'Belgium', code: 'BE' },
|
||||
{ name: 'Belize', code: 'BZ' },
|
||||
{ name: 'Benin', code: 'BJ' },
|
||||
{ name: 'Bermuda', code: 'BM' },
|
||||
{ name: 'Bhutan', code: 'BT' },
|
||||
{ name: 'Bolivia', code: 'BO' },
|
||||
{ name: 'Bosnia and Herzegovina', code: 'BA' },
|
||||
{ name: 'Botswana', code: 'BW' },
|
||||
{ name: 'Bouvet Island', code: 'BV' },
|
||||
{ name: 'Brazil', code: 'BR' },
|
||||
{ name: 'British Indian Ocean Territory', code: 'IO' },
|
||||
{ name: 'Brunei Darussalam', code: 'BN' },
|
||||
{ name: 'Bulgaria', code: 'BG' },
|
||||
{ name: 'Burkina Faso', code: 'BF' },
|
||||
{ name: 'Burundi', code: 'BI' },
|
||||
{ name: 'Cambodia', code: 'KH' },
|
||||
{ name: 'Cameroon', code: 'CM' },
|
||||
{ name: 'Canada', code: 'CA' },
|
||||
{ name: 'Cape Verde', code: 'CV' },
|
||||
{ name: 'Cayman Islands', code: 'KY' },
|
||||
{ name: 'Central African Republic', code: 'CF' },
|
||||
{ name: 'Chad', code: 'TD' },
|
||||
{ name: 'Chile', code: 'CL' },
|
||||
{ name: 'China', code: 'CN' },
|
||||
{ name: 'Christmas Island', code: 'CX' },
|
||||
{ name: 'Cocos (Keeling) Islands', code: 'CC' },
|
||||
{ name: 'Colombia', code: 'CO' },
|
||||
{ name: 'Comoros', code: 'KM' },
|
||||
{ name: 'Congo', code: 'CG' },
|
||||
{ name: 'Congo, The Democratic Republic of the', code: 'CD' },
|
||||
{ name: 'Cook Islands', code: 'CK' },
|
||||
{ name: 'Costa Rica', code: 'CR' },
|
||||
{ name: 'Cote d\'Ivoire', code: 'CI' },
|
||||
{ name: 'Croatia', code: 'HR' },
|
||||
{ name: 'Cuba', code: 'CU' },
|
||||
{ name: 'Cyprus', code: 'CY' },
|
||||
{ name: 'Czech Republic', code: 'CZ' },
|
||||
{ name: 'Denmark', code: 'DK' },
|
||||
{ name: 'Djibouti', code: 'DJ' },
|
||||
{ name: 'Dominica', code: 'DM' },
|
||||
{ name: 'Dominican Republic', code: 'DO' },
|
||||
{ name: 'Ecuador', code: 'EC' },
|
||||
{ name: 'Egypt', code: 'EG' },
|
||||
{ name: 'El Salvador', code: 'SV' },
|
||||
{ name: 'Equatorial Guinea', code: 'GQ' },
|
||||
{ name: 'Eritrea', code: 'ER' },
|
||||
{ name: 'Estonia', code: 'EE' },
|
||||
{ name: 'Ethiopia', code: 'ET' },
|
||||
{ name: 'Falkland Islands (Malvinas)', code: 'FK' },
|
||||
{ name: 'Faroe Islands', code: 'FO' },
|
||||
{ name: 'Fiji', code: 'FJ' },
|
||||
{ name: 'Finland', code: 'FI' },
|
||||
{ name: 'France', code: 'FR' },
|
||||
{ name: 'French Guiana', code: 'GF' },
|
||||
{ name: 'French Polynesia', code: 'PF' },
|
||||
{ name: 'French Southern Territories', code: 'TF' },
|
||||
{ name: 'Gabon', code: 'GA' },
|
||||
{ name: 'Gambia', code: 'GM' },
|
||||
{ name: 'Georgia', code: 'GE' },
|
||||
{ name: 'Germany', code: 'DE' },
|
||||
{ name: 'Ghana', code: 'GH' },
|
||||
{ name: 'Gibraltar', code: 'GI' },
|
||||
{ name: 'Greece', code: 'GR' },
|
||||
{ name: 'Greenland', code: 'GL' },
|
||||
{ name: 'Grenada', code: 'GD' },
|
||||
{ name: 'Guadeloupe', code: 'GP' },
|
||||
{ name: 'Guam', code: 'GU' },
|
||||
{ name: 'Guatemala', code: 'GT' },
|
||||
{ name: 'Guernsey', code: 'GG' },
|
||||
{ name: 'Guinea', code: 'GN' },
|
||||
{ name: 'Guinea-Bissau', code: 'GW' },
|
||||
{ name: 'Guyana', code: 'GY' },
|
||||
{ name: 'Haiti', code: 'HT' },
|
||||
{ name: 'Heard Island and Mcdonald Islands', code: 'HM' },
|
||||
{ name: 'Holy See (Vatican City State)', code: 'VA' },
|
||||
{ name: 'Honduras', code: 'HN' },
|
||||
{ name: 'Hong Kong', code: 'HK' },
|
||||
{ name: 'Hungary', code: 'HU' },
|
||||
{ name: 'Iceland', code: 'IS' },
|
||||
{ name: 'India', code: 'IN' },
|
||||
{ name: 'Indonesia', code: 'ID' },
|
||||
{ name: 'Iran, Islamic Republic Of', code: 'IR' },
|
||||
{ name: 'Iraq', code: 'IQ' },
|
||||
{ name: 'Ireland', code: 'IE' },
|
||||
{ name: 'Isle of Man', code: 'IM' },
|
||||
{ name: 'Israel', code: 'IL' },
|
||||
{ name: 'Italy', code: 'IT' },
|
||||
{ name: 'Jamaica', code: 'JM' },
|
||||
{ name: 'Japan', code: 'JP' },
|
||||
{ name: 'Jersey', code: 'JE' },
|
||||
{ name: 'Jordan', code: 'JO' },
|
||||
{ name: 'Kazakhstan', code: 'KZ' },
|
||||
{ name: 'Kenya', code: 'KE' },
|
||||
{ name: 'Kiribati', code: 'KI' },
|
||||
{ name: 'Korea, Democratic People\'s Republic of', code: 'KP' },
|
||||
{ name: 'Korea, Republic of', code: 'KR' },
|
||||
{ name: 'Kuwait', code: 'KW' },
|
||||
{ name: 'Kyrgyzstan', code: 'KG' },
|
||||
{ name: 'Lao People\'s Democratic Republic', code: 'LA' },
|
||||
{ name: 'Latvia', code: 'LV' },
|
||||
{ name: 'Lebanon', code: 'LB' },
|
||||
{ name: 'Lesotho', code: 'LS' },
|
||||
{ name: 'Liberia', code: 'LR' },
|
||||
{ name: 'Libyan Arab Jamahiriya', code: 'LY' },
|
||||
{ name: 'Liechtenstein', code: 'LI' },
|
||||
{ name: 'Lithuania', code: 'LT' },
|
||||
{ name: 'Luxembourg', code: 'LU' },
|
||||
{ name: 'Macao', code: 'MO' },
|
||||
{ name: 'Macedonia, The Former Yugoslav Republic of', code: 'MK' },
|
||||
{ name: 'Madagascar', code: 'MG' },
|
||||
{ name: 'Malawi', code: 'MW' },
|
||||
{ name: 'Malaysia', code: 'MY' },
|
||||
{ name: 'Maldives', code: 'MV' },
|
||||
{ name: 'Mali', code: 'ML' },
|
||||
{ name: 'Malta', code: 'MT' },
|
||||
{ name: 'Marshall Islands', code: 'MH' },
|
||||
{ name: 'Martinique', code: 'MQ' },
|
||||
{ name: 'Mauritania', code: 'MR' },
|
||||
{ name: 'Mauritius', code: 'MU' },
|
||||
{ name: 'Mayotte', code: 'YT' },
|
||||
{ name: 'Mexico', code: 'MX' },
|
||||
{ name: 'Micronesia, Federated States of', code: 'FM' },
|
||||
{ name: 'Moldova, Republic of', code: 'MD' },
|
||||
{ name: 'Monaco', code: 'MC' },
|
||||
{ name: 'Mongolia', code: 'MN' },
|
||||
{ name: 'Montserrat', code: 'MS' },
|
||||
{ name: 'Morocco', code: 'MA' },
|
||||
{ name: 'Mozambique', code: 'MZ' },
|
||||
{ name: 'Myanmar', code: 'MM' },
|
||||
{ name: 'Namibia', code: 'NA' },
|
||||
{ name: 'Nauru', code: 'NR' },
|
||||
{ name: 'Nepal', code: 'NP' },
|
||||
{ name: 'Netherlands', code: 'NL' },
|
||||
{ name: 'Netherlands Antilles', code: 'AN' },
|
||||
{ name: 'New Caledonia', code: 'NC' },
|
||||
{ name: 'New Zealand', code: 'NZ' },
|
||||
{ name: 'Nicaragua', code: 'NI' },
|
||||
{ name: 'Niger', code: 'NE' },
|
||||
{ name: 'Nigeria', code: 'NG' },
|
||||
{ name: 'Niue', code: 'NU' },
|
||||
{ name: 'Norfolk Island', code: 'NF' },
|
||||
{ name: 'Northern Mariana Islands', code: 'MP' },
|
||||
{ name: 'Norway', code: 'NO' },
|
||||
{ name: 'Oman', code: 'OM' },
|
||||
{ name: 'Pakistan', code: 'PK' },
|
||||
{ name: 'Palau', code: 'PW' },
|
||||
{ name: 'Palestinian Territory, Occupied', code: 'PS' },
|
||||
{ name: 'Panama', code: 'PA' },
|
||||
{ name: 'Papua New Guinea', code: 'PG' },
|
||||
{ name: 'Paraguay', code: 'PY' },
|
||||
{ name: 'Peru', code: 'PE' },
|
||||
{ name: 'Philippines', code: 'PH' },
|
||||
{ name: 'Pitcairn', code: 'PN' },
|
||||
{ name: 'Poland', code: 'PL' },
|
||||
{ name: 'Portugal', code: 'PT' },
|
||||
{ name: 'Puerto Rico', code: 'PR' },
|
||||
{ name: 'Qatar', code: 'QA' },
|
||||
{ name: 'Reunion', code: 'RE' },
|
||||
{ name: 'Romania', code: 'RO' },
|
||||
{ name: 'Russian Federation', code: 'RU' },
|
||||
{ name: 'RWANDA', code: 'RW' },
|
||||
{ name: 'Saint Helena', code: 'SH' },
|
||||
{ name: 'Saint Kitts and Nevis', code: 'KN' },
|
||||
{ name: 'Saint Lucia', code: 'LC' },
|
||||
{ name: 'Saint Pierre and Miquelon', code: 'PM' },
|
||||
{ name: 'Saint Vincent and the Grenadines', code: 'VC' },
|
||||
{ name: 'Samoa', code: 'WS' },
|
||||
{ name: 'San Marino', code: 'SM' },
|
||||
{ name: 'Sao Tome and Principe', code: 'ST' },
|
||||
{ name: 'Saudi Arabia', code: 'SA' },
|
||||
{ name: 'Senegal', code: 'SN' },
|
||||
{ name: 'Serbia and Montenegro', code: 'CS' },
|
||||
{ name: 'Seychelles', code: 'SC' },
|
||||
{ name: 'Sierra Leone', code: 'SL' },
|
||||
{ name: 'Singapore', code: 'SG' },
|
||||
{ name: 'Slovakia', code: 'SK' },
|
||||
{ name: 'Slovenia', code: 'SI' },
|
||||
{ name: 'Solomon Islands', code: 'SB' },
|
||||
{ name: 'Somalia', code: 'SO' },
|
||||
{ name: 'South Africa', code: 'ZA' },
|
||||
{ name: 'South Georgia and the South Sandwich Islands', code: 'GS' },
|
||||
{ name: 'Spain', code: 'ES' },
|
||||
{ name: 'Sri Lanka', code: 'LK' },
|
||||
{ name: 'Sudan', code: 'SD' },
|
||||
{ name: 'Suriname', code: 'SR' },
|
||||
{ name: 'Svalbard and Jan Mayen', code: 'SJ' },
|
||||
{ name: 'Swaziland', code: 'SZ' },
|
||||
{ name: 'Sweden', code: 'SE' },
|
||||
{ name: 'Switzerland', code: 'CH' },
|
||||
{ name: 'Syrian Arab Republic', code: 'SY' },
|
||||
{ name: 'Taiwan, Province of China', code: 'TW' },
|
||||
{ name: 'Tajikistan', code: 'TJ' },
|
||||
{ name: 'Tanzania, United Republic of', code: 'TZ' },
|
||||
{ name: 'Thailand', code: 'TH' },
|
||||
{ name: 'Timor-Leste', code: 'TL' },
|
||||
{ name: 'Togo', code: 'TG' },
|
||||
{ name: 'Tokelau', code: 'TK' },
|
||||
{ name: 'Tonga', code: 'TO' },
|
||||
{ name: 'Trinidad and Tobago', code: 'TT' },
|
||||
{ name: 'Tunisia', code: 'TN' },
|
||||
{ name: 'Turkey', code: 'TR' },
|
||||
{ name: 'Turkmenistan', code: 'TM' },
|
||||
{ name: 'Turks and Caicos Islands', code: 'TC' },
|
||||
{ name: 'Tuvalu', code: 'TV' },
|
||||
{ name: 'Uganda', code: 'UG' },
|
||||
{ name: 'Ukraine', code: 'UA' },
|
||||
{ name: 'United Arab Emirates', code: 'AE' },
|
||||
{ name: 'United Kingdom', code: 'GB' },
|
||||
{ name: 'United States', code: 'US' },
|
||||
{ name: 'United States Minor Outlying Islands', code: 'UM' },
|
||||
{ name: 'Uruguay', code: 'UY' },
|
||||
{ name: 'Uzbekistan', code: 'UZ' },
|
||||
{ name: 'Vanuatu', code: 'VU' },
|
||||
{ name: 'Venezuela', code: 'VE' },
|
||||
{ name: 'Viet Nam', code: 'VN' },
|
||||
{ name: 'Virgin Islands, British', code: 'VG' },
|
||||
{ name: 'Virgin Islands, U.S.', code: 'VI' },
|
||||
{ name: 'Wallis and Futuna', code: 'WF' },
|
||||
{ name: 'Western Sahara', code: 'EH' },
|
||||
{ name: 'Yemen', code: 'YE' },
|
||||
{ name: 'Zambia', code: 'ZM' },
|
||||
{ name: 'Zimbabwe', code: 'ZW' }
|
||||
];
|
31
accounts/src/components/basic/CountrySelector.js
Executable file
@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { countries } from './CountryList';
|
||||
|
||||
let errorStyle = {
|
||||
color:'red',
|
||||
topMargin:'5px'
|
||||
}
|
||||
|
||||
const CountrySelector = ({ input, meta: { touched, error } }) => (
|
||||
<span>
|
||||
<select {...input} className="selector" id="country">
|
||||
<option value="">Select Country...</option>
|
||||
{countries.map(val => (
|
||||
<option value={val.name} key={val.code}>
|
||||
{val.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{touched && error && <span style={errorStyle}>{error}</span>}
|
||||
</span>
|
||||
)
|
||||
|
||||
CountrySelector.displayName = 'CountrySelector'
|
||||
|
||||
CountrySelector.propTypes = {
|
||||
meta: PropTypes.object.isRequired,
|
||||
input: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default CountrySelector
|
46
accounts/src/components/basic/ErrorBoundary.js
Executable file
@ -0,0 +1,46 @@
|
||||
import React, { Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class ErrorBoundary extends Component{
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { hasError: false };
|
||||
}
|
||||
|
||||
componentDidCatch(error, info) {
|
||||
// Display fallback UI
|
||||
this.setState({ hasError: true });
|
||||
// You can also log the error to an error reporting service
|
||||
try{
|
||||
if(window.location.href.indexOf('localhost') <= -1){
|
||||
this.context.mixpanel.track('An Error has occurred',{error,info});
|
||||
}
|
||||
}catch(error){
|
||||
return error
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if(this.state.hasError) {
|
||||
return(
|
||||
<div id="app-loading" style={{ 'position': 'fixed', 'top': '0', 'bottom': '0', 'left': '0', 'right': '0', 'backgroundColor': '#e6ebf1', 'zIndex': '999', 'display': 'flex', 'justifyContent': 'center', 'alignItems': 'center' }}>
|
||||
<div>An unexpected error has occured. Please reload the page to continue</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
ErrorBoundary.displayName = 'ErrorBoundary'
|
||||
|
||||
ErrorBoundary.contextTypes = {
|
||||
mixpanel: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
ErrorBoundary.propTypes = {
|
||||
children: PropTypes.any
|
||||
}
|
||||
|
||||
export default ErrorBoundary;
|
85
accounts/src/components/basic/Loader.js
Executable file
@ -0,0 +1,85 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
let loaderStyle = {
|
||||
backgroundColor: '#96d8ff'
|
||||
}
|
||||
|
||||
export const FlatLoader = () => (<div className="ball-pulse"><div style={loaderStyle}></div><div style={loaderStyle}></div><div style={loaderStyle}></div></div>);
|
||||
|
||||
FlatLoader.displayName = 'FlatLoader'
|
||||
|
||||
export const FormLoader = () => (<div className="ball-beat"><div style={{ height: '8px', width: '8px' }}></div><div style={{ height: '8px', width: '8px' }}></div><div style={{ height: '8px', width: '8px' }}></div></div>);
|
||||
|
||||
FormLoader.displayName = 'FormLoader'
|
||||
|
||||
export const ListLoader = () => (<div className="ball-beat" style={{ textAlign: 'center', marginTop: '20px' }}><div style={{ height: '8px', width: '8px', backgroundColor: '#32325d' }}></div><div style={{ height: '8px', width: '8px', backgroundColor: '#32325d' }}></div><div style={{ height: '8px', width: '8px', backgroundColor: '#32325d' }}></div></div>);
|
||||
|
||||
ListLoader.displayName = 'ListLoader'
|
||||
|
||||
export const TeamListLoader = () => (<div className="ball-beat" style={{ textAlign: 'center',width:'95px'}}><div style={{ height: '8px', width: '8px', backgroundColor: '#32325d' }}></div><div style={{ height: '8px', width: '8px', backgroundColor: '#32325d' }}></div><div style={{ height: '8px', width: '8px', backgroundColor: '#32325d' }}></div></div>);
|
||||
|
||||
TeamListLoader.displayName = 'TeamListLoader'
|
||||
|
||||
export const Spinner = () => (
|
||||
<div className="Spinner bs-SpinnerLegacy Spinner--color--white Box-root Flex-inlineFlex Flex-alignItems--center Flex-justifyContent--center">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="Spinner-svg"
|
||||
>
|
||||
<ellipse
|
||||
cx={12}
|
||||
cy={12}
|
||||
rx={10}
|
||||
ry={10}
|
||||
className="Spinner-ellipse"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
|
||||
Spinner.displayName = 'Spinner'
|
||||
|
||||
export const LoadingState = () => (
|
||||
<div className="Box-root Margin-bottom--12">
|
||||
<div className="bs-ContentSection Card-root Card-shadow--medium">
|
||||
<div className="Box-root">
|
||||
<div className="ContentState Box-root">
|
||||
<div className="Box-root Padding-horizontal--20 Padding-vertical--48">
|
||||
<div className="Box-root Flex-flex Flex-alignItems--center Flex-direction--column Flex-justifyContent--flexStart">
|
||||
<div className="Box-root Margin-bottom--12">
|
||||
<div className="Box-root">
|
||||
<div className="Spinner bs-SpinnerLegacy Spinner--size--large Box-root Flex-flex Flex-alignItems--center Flex-justifyContent--center">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="Spinner-svg"
|
||||
>
|
||||
<ellipse
|
||||
cx={12}
|
||||
cy={12}
|
||||
rx={10}
|
||||
ry={10}
|
||||
className="Spinner-ellipse"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="Box-root">
|
||||
<div className="Box-root">
|
||||
<span className="ContentState-title Text-align--center Text-color--secondary Text-display--block Text-fontSize--14 Text-fontWeight--regular Text-lineHeight--20 Text-typeface--base Text-wrap--wrap">
|
||||
<span>Loading</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
LoadingState.displayName = 'LoadingState'
|
54
accounts/src/components/basic/RenderField.js
Executable file
@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
let errorStyle = {
|
||||
color:'red',
|
||||
topMargin:'5px'
|
||||
}
|
||||
|
||||
const RenderField = ({ input, placeholder, type, meta, className, id, disabled, initialValue, style }) => (
|
||||
|
||||
<span>
|
||||
<span>
|
||||
<input
|
||||
{...input}
|
||||
type={type}
|
||||
placeholder={placeholder}
|
||||
className={className}
|
||||
id={id}
|
||||
disabled={disabled || false}
|
||||
defaultValue={initialValue}
|
||||
style={style || {}}
|
||||
/>
|
||||
</span>
|
||||
<br/>
|
||||
{meta.error &&
|
||||
meta.touched &&
|
||||
<span style={errorStyle}>
|
||||
{meta.error}
|
||||
</span>}
|
||||
</span>
|
||||
)
|
||||
|
||||
RenderField.displayName = 'RenderField'
|
||||
|
||||
RenderField.propTypes = {
|
||||
initialValue: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.bool,
|
||||
]),
|
||||
input: PropTypes.object.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
type: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
meta: PropTypes.object.isRequired,
|
||||
rows: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
style: PropTypes.object
|
||||
}
|
||||
|
||||
export {RenderField}
|
||||
|
||||
|
||||
|
359
accounts/src/config.js
Executable file
@ -0,0 +1,359 @@
|
||||
import React from 'react';
|
||||
import isEmail from 'sane-email-validation';
|
||||
import validUrl from 'valid-url';
|
||||
import valid from 'card-validator';
|
||||
import { isServer } from './store';
|
||||
import FileSaver from 'file-saver';
|
||||
import { emaildomains } from './constants/emaildomains';
|
||||
|
||||
let apiUrl = 'http://localhost:3002';
|
||||
let dashboardUrl = null;
|
||||
let domain = null;
|
||||
|
||||
if (!isServer) {
|
||||
if (window.location.href.indexOf('localhost') > -1) {
|
||||
apiUrl = 'http://localhost:3002';
|
||||
dashboardUrl = 'http://localhost:3000';
|
||||
domain = 'localhost';
|
||||
} else if (window.location.href.indexOf('staging') > -1) {
|
||||
apiUrl = 'https://staging-api.fyipe.com';
|
||||
dashboardUrl = 'http://staging-dashboard.fyipe.com';
|
||||
domain = 'fyipe.com';
|
||||
} else {
|
||||
apiUrl = 'https://api.fyipe.com';
|
||||
dashboardUrl = 'https://dashboard.fyipe.com';
|
||||
domain = 'fyipe.com';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export const API_URL = apiUrl;
|
||||
|
||||
export const DASHBOARD_URL = dashboardUrl;
|
||||
|
||||
export const DOMAIN_URL = domain;
|
||||
|
||||
export const User = {
|
||||
|
||||
getAccessToken() {
|
||||
return localStorage.getItem('access_token');
|
||||
},
|
||||
|
||||
setAccessToken(token) {
|
||||
localStorage.setItem('access_token', token);
|
||||
},
|
||||
|
||||
isCardRegistered() {
|
||||
return localStorage.getItem('cardRegistered');
|
||||
},
|
||||
|
||||
setCardRegistered(value) {
|
||||
localStorage.setItem('cardRegistered', value);
|
||||
},
|
||||
|
||||
setUserId(id) {
|
||||
localStorage.setItem('id', id);
|
||||
},
|
||||
|
||||
getUserId() {
|
||||
return localStorage.getItem('id');
|
||||
},
|
||||
|
||||
getName() {
|
||||
return localStorage.getItem('name');
|
||||
},
|
||||
|
||||
setName(name) {
|
||||
localStorage.setItem('name', name);
|
||||
},
|
||||
|
||||
getEmail() {
|
||||
return localStorage.getItem('email');
|
||||
},
|
||||
|
||||
setEmail(email) {
|
||||
localStorage.setItem('email', email);
|
||||
},
|
||||
initialUrl() {
|
||||
return sessionStorage.getItem('initialUrl');
|
||||
},
|
||||
setProject(project) {
|
||||
localStorage.setItem('project', project);
|
||||
},
|
||||
|
||||
getProject() {
|
||||
return localStorage.getItem('project');
|
||||
},
|
||||
|
||||
clear() {
|
||||
localStorage.clear();
|
||||
},
|
||||
|
||||
removeUserId() {
|
||||
localStorage.removeItem('id');
|
||||
},
|
||||
|
||||
removeAccessToken() {
|
||||
localStorage.removeItem('token');
|
||||
},
|
||||
|
||||
isLoggedIn() {
|
||||
return localStorage.getItem('access_token') ? true : false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//Data validation Util goes in here.
|
||||
export const Validate = {
|
||||
|
||||
isDomain(domain) {
|
||||
return (domain.search(/\./) >= 0);
|
||||
},
|
||||
|
||||
url(url) {
|
||||
return validUrl.isUri(url);
|
||||
},
|
||||
|
||||
text(text) {
|
||||
|
||||
if (!text || text.trim() === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
number(number) {
|
||||
|
||||
if (number && number.length && !isNaN(number)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
email(email) {
|
||||
if (this.text(email))
|
||||
return isEmail(email);
|
||||
return false;
|
||||
},
|
||||
|
||||
isValidBusinessEmail(email){
|
||||
return emaildomains.test(email);
|
||||
},
|
||||
|
||||
compare(text1, text2) {
|
||||
return text1 === text2;
|
||||
},
|
||||
|
||||
card(cardNumber) {
|
||||
var numberValidation = valid.number(cardNumber);
|
||||
|
||||
if (!numberValidation.isPotentiallyValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
cardExpiration(expiry) {
|
||||
var numberValidation = valid.expirationDate(expiry);
|
||||
|
||||
if (!numberValidation.isPotentiallyValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
cvv(cvv) {
|
||||
var numberValidation = valid.cvv(cvv);
|
||||
|
||||
if (!numberValidation.isPotentiallyValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
postalCode(postalCode) {
|
||||
var numberValidation = valid.postalCode(postalCode);
|
||||
|
||||
if (!numberValidation.isPotentiallyValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export const PricingPlan = {
|
||||
|
||||
getPlans() {
|
||||
|
||||
if (window.location.href.indexOf('localhost') > -1 || window.location.href.indexOf('staging') > -1) {
|
||||
return [
|
||||
{
|
||||
category: 'Basic',
|
||||
planId: 'plan_EgTJMZULfh6THW',
|
||||
type: 'Month',
|
||||
amount: 8,
|
||||
details: '$8 / Month / User'
|
||||
},
|
||||
{
|
||||
category: 'Basic',
|
||||
planId: 'plan_EgTQAx3Z909Dne',
|
||||
type: 'Annual',
|
||||
amount: 80.4,
|
||||
details: '$80.4 / Year / User'
|
||||
},
|
||||
/* {
|
||||
category: 'Pro',
|
||||
planId: 'plan_CpIZEEfT4YFSvF',
|
||||
type: 'month',
|
||||
amount: 49,
|
||||
details: '$49 / Month'
|
||||
},
|
||||
{
|
||||
category: 'Pro',
|
||||
planId: 'plan_CpIZTQWQiIr6rY',
|
||||
type: 'annual',
|
||||
amount: 708,
|
||||
details: '$708 / Year'
|
||||
},
|
||||
{
|
||||
category: 'Pro Plus',
|
||||
planId: 'plan_CpIatF9qAmeZLP',
|
||||
type: 'month',
|
||||
amount: 99,
|
||||
details: '$99 / Month'
|
||||
},
|
||||
{
|
||||
category: 'Pro Plus',
|
||||
planId: 'plan_CpIbtqozj1UVGs',
|
||||
type: 'annual',
|
||||
amount: 1180,
|
||||
details: '$1180 / Year'
|
||||
} */
|
||||
]
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
category: 'Basic',
|
||||
planId: 'plan_EgT8cUrwsxaqCs',
|
||||
type: 'Month',
|
||||
amount: 8,
|
||||
details: '$8 / Month / User'
|
||||
},
|
||||
{
|
||||
category: 'Basic',
|
||||
planId: 'plan_EgT9hrq9GdIGQ6',
|
||||
type: 'Annual',
|
||||
amount: 80.4,
|
||||
details: '$80.4 / Year / User'
|
||||
},
|
||||
/* {
|
||||
category: 'Pro',
|
||||
planId: 'plan_CogeidQkPwkycV',
|
||||
type: 'month',
|
||||
amount: 49,
|
||||
details: '$49 / Month'
|
||||
},
|
||||
{
|
||||
category: 'Pro',
|
||||
planId: 'plan_CogfwRVpqoOLO6',
|
||||
type: 'annual',
|
||||
amount: 708,
|
||||
details: '$708 / Year'
|
||||
},
|
||||
{
|
||||
category: 'Pro Plus',
|
||||
planId: 'prod_Cogffh2xpitVg6',
|
||||
type: 'month',
|
||||
amount: 99,
|
||||
details: '$99 / Month'
|
||||
},
|
||||
{
|
||||
category: 'Pro Plus',
|
||||
planId: 'plan_CoggNmls8dUpDy',
|
||||
type: 'annual',
|
||||
amount: 1180,
|
||||
details: '$1180 / Year'
|
||||
}*/
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
getPlanById(id) {
|
||||
let plans = this.getPlans();
|
||||
if (id) return plans.find(plan => plan.planId === id);
|
||||
else return plans[0];
|
||||
},
|
||||
}
|
||||
|
||||
export const tutorials = {
|
||||
|
||||
getMonitorTutorials() {
|
||||
return [
|
||||
{
|
||||
id: 's1',
|
||||
title: 'What are Monitors',
|
||||
icon: 'bell',
|
||||
description: <p>You can add web and API server address to
|
||||
to monitor.<br />It allows you monitor the health status of
|
||||
your API</p>,
|
||||
},
|
||||
{
|
||||
id: 's2',
|
||||
title: 'What are Incidents',
|
||||
icon: 'bell',
|
||||
description: <p>You can use this feature to acknowledge an incident
|
||||
that occurred on a monitor<br /> and mark the
|
||||
incident as resolved after resolving the
|
||||
issue on your api or server</p>,
|
||||
},
|
||||
{
|
||||
id: 's3',
|
||||
title: 'Acknowledge/Resolve Incidents',
|
||||
icon: 'bell',
|
||||
description: <p>You can use this feature to acknowledge an incident
|
||||
that occurred on a monitor<br /> and mark the
|
||||
incident as resolved after resolving the
|
||||
issue on your api or server</p>,
|
||||
},
|
||||
{
|
||||
id: 's4',
|
||||
title: 'Status Metrics',
|
||||
icon: 'bell',
|
||||
description: <p>Get detailed metrics of all incidents that occurred <br />
|
||||
on connected monitors and with date and time it was resolved
|
||||
</p>,
|
||||
},
|
||||
{
|
||||
id: 's5',
|
||||
title: 'Better Status Handling',
|
||||
icon: 'bell',
|
||||
description: <p>After adding monitors for your API, you won"t miss out on any<br />
|
||||
downtime on your servers, Just let Fyipe alert notify you
|
||||
</p>,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export function getQueryVar(variable, url) {
|
||||
if (!url) return null;
|
||||
variable = variable.replace(/[[\]]/g, '\\$&');
|
||||
var regex = new RegExp('[?&]' + variable + '(=([^&#]*)|&|#|$)'),
|
||||
results = regex.exec(url);
|
||||
if (!results) return null;
|
||||
if (!results[2]) return '';
|
||||
return decodeURIComponent(results[2].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
export function saveFile(content, filename){
|
||||
var blob = new Blob([content], {type: 'text/plain;charset=utf-8'});
|
||||
FileSaver.saveAs(blob, filename);
|
||||
}
|
6
accounts/src/constants/changePassword.js
Executable file
@ -0,0 +1,6 @@
|
||||
// There are three possible states for our changePassword
|
||||
// process and we need actions for each of them
|
||||
export const CHANGEPASSWORD_SUCCESS = 'auth/CHANGEPASSWORD_SUCCESS';
|
||||
export const CHANGEPASSWORD_FAILED = 'auth/CHANGEPASSWORD_FAILED';
|
||||
export const CHANGEPASSWORD_REQUEST = 'auth/CHANGEPASSWORD_REQUEST';
|
||||
export const RESET_CHANGEPASSWORD = 'auth/RESET_CHANGEPASSWORD';
|
6
accounts/src/constants/emaildomains.js
Executable file
4
accounts/src/constants/login.js
Executable file
@ -0,0 +1,4 @@
|
||||
export const LOGIN_SUCCESS = 'auth/LOGIN_SUCCESS';
|
||||
export const LOGIN_FAILED = 'auth/LOGIN_FAILED';
|
||||
export const LOGIN_REQUEST = 'auth/LOGIN_REQUEST';
|
||||
export const RESET_LOGIN = 'auth/RESET_LOGIN';
|
2
accounts/src/constants/modal.js
Executable file
@ -0,0 +1,2 @@
|
||||
export const OPEN_MODAL = 'OPEN_MODAL';
|
||||
export const CLOSE_MODAL = 'CLOSE_MODAL';
|
17
accounts/src/constants/register.js
Executable file
@ -0,0 +1,17 @@
|
||||
export const SIGNUP_SUCCESS = 'register/SIGNUP_SUCCESS';
|
||||
export const SIGNUP_FAILED = 'register/SIGNUP_FAILED';
|
||||
export const SIGNUP_STEP_INC = 'register/SIGNUP_STEP_INC';
|
||||
export const SIGNUP_STEP_DEC = 'register/SIGNUP_STEP_DEC';
|
||||
export const SIGNUP_REQUEST = 'register/SIGNUP_REQUEST';
|
||||
export const RESET_SIGNUP = 'register/RESET_SIGNUP';
|
||||
export const SAVE_USER_STATE = 'register/SAVE_USER_STATE';
|
||||
export const SAVE_CARD_STATE = 'register/SAVE_CARD_STATE';
|
||||
export const SAVE_COMPANY_STATE = 'register/SAVE_COMPANY_STATE';
|
||||
|
||||
export const IS_USER_INVITED_REQUEST = 'register/IS_USER_INVITED_FETCH';
|
||||
export const IS_USER_INVITED_FAILED = 'register/IS_USER_INVITED_FAILED';
|
||||
export const IS_USER_INVITED_SUCCESS = 'register/IS_USER_INVITED_SUCCESS';
|
||||
export const IS_USER_INVITED_RESET = 'register/IS_USER_INVITED_RESET';
|
||||
export const IS_USER_INVITED_FETCH = 'register/IS_USER_INVITED_FETCH'
|
||||
|
||||
export const SKIP_CARD_STEP = 'register/SKIP_CARD_STEP';
|
3
accounts/src/constants/resendToken.js
Executable file
@ -0,0 +1,3 @@
|
||||
export const RESENDTOKEN_SUCCESS = 'auth/RESENDTOKEN_SUCCESS';
|
||||
export const RESENDTOKEN_FAILED = 'auth/RESENDTOKEN_FAILED';
|
||||
export const RESENDTOKEN_REQUEST = 'auth/RESENDTOKEN_REQUEST';
|
4
accounts/src/constants/resetPassword.js
Executable file
@ -0,0 +1,4 @@
|
||||
export const PASSWORDRESET_SUCCESS = 'auth/PASSWORDRESET_SUCCESS';
|
||||
export const PASSWORDRESET_FAILED = 'auth/PASSWORDRESET_FAILED';
|
||||
export const PASSWORDRESET_REQUEST = 'auth/PASSWORDRESET_REQUEST';
|
||||
export const RESET_PASSWORDRESET = 'auth/RESET_PASSWORDRESET';
|
46
accounts/src/containers/BackboneModals.js
Executable file
@ -0,0 +1,46 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import Modal from '../components/Modal';
|
||||
import { closeModal } from '../actions/modal';
|
||||
|
||||
export class Modals extends Component {
|
||||
render() {
|
||||
const modals = this.props.modals.map((item, i) => {
|
||||
const ModalComponent = Modal(item.content);
|
||||
return (
|
||||
// Modal(item.content)({
|
||||
// item,
|
||||
// zIndex: i,
|
||||
// key: i,
|
||||
// onClose: item => this.props.closeModal(item)
|
||||
// })
|
||||
<ModalComponent
|
||||
item={item}
|
||||
key={i}
|
||||
zIndex={i}
|
||||
onClose={item => this.props.closeModal(item)}
|
||||
/>
|
||||
)});
|
||||
return <div id="backboneModals">{modals}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Modals.propTypes = {
|
||||
modals: PropTypes.array.isRequired,
|
||||
closeModal: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
Modals.displayName = 'BlackBoneModals'
|
||||
|
||||
export default connect(
|
||||
function mapStateToProps(state) {
|
||||
return state.modal
|
||||
},
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators({
|
||||
closeModal
|
||||
}, dispatch);
|
||||
}
|
||||
)(Modals);
|
8
accounts/src/errors.js
Executable file
@ -0,0 +1,8 @@
|
||||
export default (error)=>{
|
||||
switch (error.toString()){
|
||||
case 'Error: Network Error':
|
||||
return 'Check your network connection.'
|
||||
default:
|
||||
return error
|
||||
}
|
||||
}
|
4
accounts/src/index.css
Executable file
@ -0,0 +1,4 @@
|
||||
body {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
32
accounts/src/index.js
Executable file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { Frontload } from 'react-frontload';
|
||||
// import { ConnectedRouter } from 'connected-react-router';
|
||||
import MixpanelProvider from 'react-mixpanel';
|
||||
import mixpanel from 'mixpanel-browser';
|
||||
import * as CB from 'cloudboost';
|
||||
import ReactGA from 'react-ga';
|
||||
import ErrorBoundary from './components/basic/ErrorBoundary';
|
||||
import { render } from 'react-dom';
|
||||
import store, { history, isServer } from './store';
|
||||
import App from './App';
|
||||
import './index.css';
|
||||
|
||||
if (!isServer) {
|
||||
ReactGA.initialize('UA-115085157-1');
|
||||
CB.CloudApp.init('hcaarmonukbk', 'cdcc37f4-dfc6-44e0-b61b-de8c887ec202');
|
||||
mixpanel.init('de27af9b37fa926bf648bb704836fd5f');
|
||||
}
|
||||
const target = document.getElementById('root');
|
||||
|
||||
render (
|
||||
<Provider store={store} history={history}>
|
||||
<Frontload noServerRender={true}>
|
||||
<MixpanelProvider mixpanel={mixpanel}>
|
||||
<ErrorBoundary>
|
||||
<App />
|
||||
</ErrorBoundary>
|
||||
</MixpanelProvider>
|
||||
</Frontload>
|
||||
</Provider>,target
|
||||
);
|
82
accounts/src/pages/ChangePassword.js
Executable file
@ -0,0 +1,82 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Link } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import ChangePasswordForm from '../components/auth/ChangePasswordForm';
|
||||
import { history } from '../store';
|
||||
|
||||
class ChangePasswordPage extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.token = this.props.match.params.token;
|
||||
|
||||
//if token is not present. Redirect to login page.
|
||||
if (!this.token) {
|
||||
history.push('/login');
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="wrap" style={{ paddingTop: 0 }}>
|
||||
{/* Header */}
|
||||
<div id="header">
|
||||
<h1>
|
||||
<a href="/">Fyipe</a>
|
||||
</h1>
|
||||
</div>
|
||||
{/* RESET PASSWORD BOX */}
|
||||
<ChangePasswordForm token={this.token} />
|
||||
<div className="below-box">
|
||||
<p>
|
||||
<Link to="/login">
|
||||
Know your password? <strong>Sign in</strong>.
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
{/* END CONTENT */}
|
||||
<div id="footer_spacer" />
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<Link to="/register">Sign Up</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/legal/privacy">Privacy Policy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/support">Support</a>
|
||||
</li>
|
||||
<li className="last">
|
||||
<a href="https://hackerbay.io">© HackerBay, Inc.</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state_Ignored => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch_Ignored => {
|
||||
return null;
|
||||
}
|
||||
|
||||
ChangePasswordPage.propTypes = {
|
||||
match: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
ChangePasswordPage.displayName = 'ChangePasswordPage'
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ChangePasswordPage);
|
98
accounts/src/pages/Login.js
Executable file
@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Link } from 'react-router-dom';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import LoginForm from '../components/auth/LoginForm';
|
||||
import { loginUser, loginError } from '../actions/login';
|
||||
import MessageBox from '../components/MessageBox';
|
||||
|
||||
class LoginPage extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
submitHandler = (values) => {
|
||||
let thisObj = this;
|
||||
this.props.loginUser(values).then((user) => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if(window.location.href.indexOf('localhost') <= -1){
|
||||
thisObj.context.mixpanel.identify(user.data.id);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div id="wrap">
|
||||
<div id="header">
|
||||
<h1>
|
||||
<a aria-hidden={false} href="/">Fyipe</a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* LOGIN BOX */}
|
||||
{!this.props.login.success && this.props.login.error ? <MessageBox title={'Your email is not verified.'} message={'An email is on its way to you with new verification link. Please don't forget to check spam. '}/> :
|
||||
<LoginForm onSubmit={this.submitHandler} {...this.props} />}
|
||||
|
||||
{/* FOOTER */}
|
||||
<div className="below-box">
|
||||
<p>
|
||||
Don't have an account? <Link to="/register">Sign up</Link>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* END FOOTER */}
|
||||
<div id="footer_spacer" />
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
<li>
|
||||
<Link to="/forgot-password">Forgot Password</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/legal/privacy">Privacy Policy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/support">Support</a>
|
||||
</li>
|
||||
<li className="last">
|
||||
<a href="https://hackerbay.io">© HackerBay, Inc.</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
login: state.login
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => bindActionCreators(
|
||||
{ loginUser, loginError }, dispatch);
|
||||
|
||||
LoginPage.propTypes = {
|
||||
loginUser: PropTypes.func.isRequired,
|
||||
login: PropTypes.object,
|
||||
success: PropTypes.bool,
|
||||
error: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.bool,
|
||||
]),
|
||||
}
|
||||
|
||||
LoginPage.displayName = 'LoginPage'
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LoginPage);
|
89
accounts/src/pages/Register.js
Executable file
@ -0,0 +1,89 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Link } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import RegisterForm from '../components/auth/RegisterForm';
|
||||
import queryString from 'query-string';
|
||||
import {PricingPlan} from '../config';
|
||||
import MessageBox from '../components/MessageBox';
|
||||
|
||||
class RegisterPage extends React.Component {
|
||||
|
||||
componentWillUnmount() {
|
||||
document.body.id = '';
|
||||
document.body.className = '';
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.className = 'register-page';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
render() {
|
||||
this.planId = queryString.parse(this.props.location.search).planId || null;
|
||||
|
||||
if(!this.planId){
|
||||
this.planId = PricingPlan.getPlans()[0].planId;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
<div id="wrap" style={{ paddingTop: 0 }}>
|
||||
{/* Header */}
|
||||
<div id="header">
|
||||
<h1>
|
||||
<a href="/">Fyipe</a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* REGISTRATION BOX */}
|
||||
{this.props.register.success ? <MessageBox title="Activate your Fyipe account" message="An email is on its way to you with a verification link. Please don't forget to check spam. "/> :
|
||||
<RegisterForm planId={this.planId} location={this.props.location}/>}
|
||||
{/* END CONTENT */}
|
||||
<div className="below-box">
|
||||
<p>
|
||||
Already have an account? <Link to="/login">Sign in</Link>.
|
||||
</p>
|
||||
</div>
|
||||
<div id="footer_spacer" />
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
<li>
|
||||
<Link to="/forgot-password">Forgot Password</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/legal/privacy">Privacy Policy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/support">Support</a>
|
||||
</li>
|
||||
<li className="last">
|
||||
<a href="https://hackerbay.io">© HackerBay, Inc.</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
register: state.register
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch_Ignored =>{
|
||||
return {};
|
||||
};
|
||||
|
||||
RegisterPage.propTypes = {
|
||||
location: PropTypes.object.isRequired,
|
||||
register:PropTypes.object,
|
||||
success:PropTypes.bool,
|
||||
}
|
||||
|
||||
RegisterPage.displayName = 'RegisterPage'
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(RegisterPage);
|
164
accounts/src/pages/ResendToken.js
Executable file
@ -0,0 +1,164 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { Validate } from '../config';
|
||||
import { FlatLoader } from '../components/basic/Loader';
|
||||
import { resendToken } from '../actions/resendToken';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { RenderField } from '../components/basic/RenderField';
|
||||
import { Link } from 'react-router-dom';
|
||||
import queryString from 'query-string';
|
||||
import { removeQuery } from '../store';
|
||||
|
||||
|
||||
export class ResendTokenForm extends Component {
|
||||
state = {
|
||||
serverResponse: ''
|
||||
}
|
||||
|
||||
submitForm = (values) => {
|
||||
this.props.resendToken(values);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
var query = queryString.parse(this.props.location.search).status;
|
||||
if(query === 'Lc5orxwR5nKxTANs8jfNsCvGD8Us9ltq'){
|
||||
this.setState({
|
||||
serverResponse: 'Verification link expired.'
|
||||
});
|
||||
}
|
||||
else if(query === 'eG5aFRDeZXgOkjEfdhOYbFb2lA3Z0OJm'){
|
||||
this.setState({
|
||||
serverResponse: 'Invalid Verification link.'
|
||||
});
|
||||
}
|
||||
removeQuery();
|
||||
}
|
||||
render() {
|
||||
const { serverResponse } = this.state;
|
||||
const { success } = this.props.resendTokenState;
|
||||
return (
|
||||
<div id="wrap" style={{ paddingTop: 0 }}>
|
||||
<div id="header">
|
||||
<h1>
|
||||
<a href="/">Fyipe</a>
|
||||
</h1>
|
||||
</div>
|
||||
<div id="main-body" className="box css">
|
||||
<div className="inner">
|
||||
<form onSubmit={this.props.handleSubmit(this.submitForm)} className="request-reset">
|
||||
<div className="request-reset-step step" >
|
||||
<div className="title">
|
||||
<h2>
|
||||
{success ? <span>Verification link Sent</span> :
|
||||
serverResponse ? <span>{serverResponse}</span> :
|
||||
<span > {this.props.resendTokenState.error ?
|
||||
<span id="error-msg" className="error" >{this.props.resendTokenState.error}</span>
|
||||
: 'Resend verification email'} </span>}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<p className="error-message hidden" />
|
||||
|
||||
|
||||
{this.props.resendTokenState.success && <p id="reset-password-success" className="message"> An email is on its way to you with new verification link. Please don't forget to check spam. </p>}
|
||||
{!this.props.resendTokenState.success && <p className="message"> Enter your email address below and we will resend you a verification link to activate your fyipe account.</p>}
|
||||
|
||||
|
||||
{!this.props.resendTokenState.success && <div> <p className="text">
|
||||
<span>
|
||||
<label htmlFor="email"> Your Email</label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="email"
|
||||
name="email"
|
||||
id="email"
|
||||
placeholder="Your Email"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" disabled={this.props.resendTokenState.requesting}>
|
||||
{!this.props.resendTokenState.requesting && <span>Send Verification Link</span>}
|
||||
{this.props.resendTokenState.requesting && <FlatLoader />}
|
||||
</button>
|
||||
</p> </div>}
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="below-box">
|
||||
<p>
|
||||
<Link to="/login">
|
||||
Know your password? <strong>Sign in</strong>.
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
<div id="footer_spacer" />
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<Link to="/register">Sign Up</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/legal/privacy">Privacy Policy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/support">Support</a>
|
||||
</li>
|
||||
<li className="last">
|
||||
<a href="https://hackerbay.io">© HackerBay, Inc.</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ResendTokenForm.displayName = 'ResendTokenForm'
|
||||
|
||||
function validate(values) {
|
||||
let errors = {};
|
||||
if (!Validate.text(values.email)) {
|
||||
errors.email = 'Email is required.'
|
||||
}
|
||||
else if (!Validate.email(values.email)) {
|
||||
errors.email = 'Email is invalid.'
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
let resendTokenForm = reduxForm({
|
||||
form: 'resendTokenForm',
|
||||
validate
|
||||
})(ResendTokenForm);
|
||||
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
resendToken
|
||||
}, dispatch);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
resendTokenState: state.resendToken
|
||||
};
|
||||
}
|
||||
|
||||
ResendTokenForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
resendTokenState: PropTypes.object.isRequired,
|
||||
resendToken: PropTypes.func.isRequired,
|
||||
location: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(resendTokenForm);
|
57
accounts/src/pages/ResetPassword.js
Executable file
@ -0,0 +1,57 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import ResetPasswordForm from '../components/auth/ResetPasswordForm';
|
||||
|
||||
class ResetPasswordPage extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="wrap" style={{ paddingTop: 0 }}>
|
||||
{/* Header */}
|
||||
<div id="header">
|
||||
<h1>
|
||||
<a href="/">Fyipe</a>
|
||||
</h1>
|
||||
</div>
|
||||
{/* RESET PASSWORD BOX */}
|
||||
<ResetPasswordForm />
|
||||
<div className="below-box">
|
||||
<p>
|
||||
<Link to="/login">
|
||||
Know your password? <strong>Sign in</strong>.
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
{/* END CONTENT */}
|
||||
<div id="footer_spacer" />
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<Link to="/register">Sign Up</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/legal/privacy">Privacy Policy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fyipe.com/support">Support</a>
|
||||
</li>
|
||||
<li className="last">
|
||||
<a href="https://hackerbay.io">© HackerBay, Inc.</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ResetPasswordPage.displayName = 'ResetPasswordPage'
|
||||
|
||||
export default connect(null, null)(ResetPasswordPage);
|