mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
Lint projects
This commit is contained in:
@@ -19,7 +19,6 @@ is referred to as the “Fyipe Software” and a license for Fyipe Software is a
|
||||
|
||||
You may not use the Container Image if you do not have a corresponding version and edition of the Fyipe License. Certain restrictions and additional terms may apply, which are described herein. If licensing terms herein conflict with Fyipe License, then this Supplemental License shall govern with respect to the Container Image. BY ACCEPTING THIS SUPPLEMENTAL LICENSE OR USING THE CONTAINER IMAGE, YOU AGREE TO ALL OF THESE TERMS. IF YOU DO NOT ACCEPT AND COMPLY WITH THESE TERMS, YOU MAY NOT USE THE CONTAINER IMAGE.
|
||||
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
Fyipe License. The Fyipe License terms apply to your use of the Container Image and any Fyipe container(s) created with the Container Image which are distinct and separate from a virtual machine.
|
||||
@@ -32,8 +31,8 @@ ADDITIONAL TERMS
|
||||
|
||||
Fyipe Software - When running a Container Image on Client Fyipe Software you may run any number of the Container Image instantiated as Fyipe containers for test or development purposes only. You may not use these Fyipe containers in a production environment.
|
||||
|
||||
Third Party Software. The Container Image may include third party applications that are licensed to you under this Supplemental License or under their own terms.
|
||||
Third Party Software. The Container Image may include third party applications that are licensed to you under this Supplemental License or under their own terms.
|
||||
|
||||
Open Source Components. The Container Image may contain third party copyrighted software licensed under open source licenses.
|
||||
|
||||
Production Use. You may not use this Fyipe Docker Image or any other Docker Images by Fyipe in production unless you have an active Enterprise Subscription. To request or buy an enterprise subscription or license - please contact our sales team at sales@fyipe.com
|
||||
Production Use. You may not use this Fyipe Docker Image or any other Docker Images by Fyipe in production unless you have an active Enterprise Subscription. To request or buy an enterprise subscription or license - please contact our sales team at sales@fyipe.com
|
||||
|
||||
63
README.md
63
README.md
@@ -1,43 +1,44 @@
|
||||
# Fyipe
|
||||
# Fyipe
|
||||
|
||||
## Project Architecture
|
||||
|
||||
TODO
|
||||
|
||||
## Description of the projects in this repo.
|
||||
- `accounts` - A React project used for Authentication (Log in, Sign up, Forgot Password, etc.)
|
||||
- `dashboard` - A React project for Fyipe user where user can interact with the Fyipe platform.
|
||||
- `admin-dashobard` - React Project where admin can block users, delete projects and more.
|
||||
- `api-docs` - HTML/CSS project. A public reference of Fyipe documentation.
|
||||
- `backend` - NodeJS Service. It's Fyipe API's.
|
||||
- `home` - HTML/CSS. Home Page / Marketing page of Fyipe.
|
||||
- `http-test-server` - A test server used to test website monitors for Fyipe.
|
||||
- `kubernetes` - yaml files to deploy fyipe on staging, production or any enterprise kubernetes cluster. This also contains DevOps/CI/CD scripts.
|
||||
- `marketing` - This is where you'll find logos, brief description of Fyipe, etc.
|
||||
- `certifications` - SOC/ISO/PCI certifications and more.
|
||||
- `postman-collection` - Postman collection for Fyipe API.
|
||||
- `probe` - Probe is an agent that gets insalled on a third party server on a thir party datacenter and it monitors users websites, services, from that data center. You can deploy multiple probes to monitor users resources - A probe in a datacenter in EU, in US, etc.
|
||||
- `server-monitor` - A probe that gets installed on a server and that monitors that particular server.
|
||||
- `smoke-test` - Smoke test that is executed after Fyipe is deployed to staging or production. If smoke test fails, the staging / production deployment will automatically be rolled back.
|
||||
- `status-page` - React project - Status page project of Fyipe.
|
||||
- `zapier` - Fyipe integrates with zapier. This is where integration code is. This gets deployed to zapier directly.
|
||||
- `init-script` - a container that runs schema migration script.
|
||||
## Description of the projects in this repo.
|
||||
|
||||
## Running this project in local environment.
|
||||
- `accounts` - A React project used for Authentication (Log in, Sign up, Forgot Password, etc.)
|
||||
- `dashboard` - A React project for Fyipe user where user can interact with the Fyipe platform.
|
||||
- `admin-dashobard` - React Project where admin can block users, delete projects and more.
|
||||
- `api-docs` - HTML/CSS project. A public reference of Fyipe documentation.
|
||||
- `backend` - NodeJS Service. It's Fyipe API's.
|
||||
- `home` - HTML/CSS. Home Page / Marketing page of Fyipe.
|
||||
- `http-test-server` - A test server used to test website monitors for Fyipe.
|
||||
- `kubernetes` - yaml files to deploy fyipe on staging, production or any enterprise kubernetes cluster. This also contains DevOps/CI/CD scripts.
|
||||
- `marketing` - This is where you'll find logos, brief description of Fyipe, etc.
|
||||
- `certifications` - SOC/ISO/PCI certifications and more.
|
||||
- `postman-collection` - Postman collection for Fyipe API.
|
||||
- `probe` - Probe is an agent that gets insalled on a third party server on a thir party datacenter and it monitors users websites, services, from that data center. You can deploy multiple probes to monitor users resources - A probe in a datacenter in EU, in US, etc.
|
||||
- `server-monitor` - A probe that gets installed on a server and that monitors that particular server.
|
||||
- `smoke-test` - Smoke test that is executed after Fyipe is deployed to staging or production. If smoke test fails, the staging / production deployment will automatically be rolled back.
|
||||
- `status-page` - React project - Status page project of Fyipe.
|
||||
- `zapier` - Fyipe integrates with zapier. This is where integration code is. This gets deployed to zapier directly.
|
||||
- `init-script` - a container that runs schema migration script.
|
||||
|
||||
- Before you run this project locally, please make sure you're on Ubuntu or on a Mac machine.
|
||||
- Install Docker and Docker Compose.
|
||||
- Install Robomongo / Mongo Compass / or any other MongoDB UI Tool.
|
||||
- Make sure MongoDB and Redis are NOT running (NO services should run on port 27017 and 6379)
|
||||
- Run `sudo bash install.sh` - This will take some time (30 mins maybe or more) when you run this for the first time.
|
||||
- The above command runs the entire project in Docker Compose.
|
||||
- If you're working on particular sub-project (for ex: accounts, admin-dashboard or literally anything else), your changes will not be reflected in Docker Compose automatically. In this case
|
||||
- Delete the docker container of the project you're working on. (`sudo docker stop containerId` and `sudo docker rm containerId`)
|
||||
- Once the container is deleted, cd into that project run `npm install` and `npm run dev`.
|
||||
- Let other projects / containers run on docker. They will work perfectly fine with a project you're working on.
|
||||
## Running this project in local environment.
|
||||
|
||||
- Before you run this project locally, please make sure you're on Ubuntu or on a Mac machine.
|
||||
- Install Docker and Docker Compose.
|
||||
- Install Robomongo / Mongo Compass / or any other MongoDB UI Tool.
|
||||
- Make sure MongoDB and Redis are NOT running (NO services should run on port 27017 and 6379)
|
||||
- Run `sudo bash install.sh` - This will take some time (30 mins maybe or more) when you run this for the first time.
|
||||
- The above command runs the entire project in Docker Compose.
|
||||
- If you're working on particular sub-project (for ex: accounts, admin-dashboard or literally anything else), your changes will not be reflected in Docker Compose automatically. In this case
|
||||
- Delete the docker container of the project you're working on. (`sudo docker stop containerId` and `sudo docker rm containerId`)
|
||||
- Once the container is deleted, cd into that project run `npm install` and `npm run dev`.
|
||||
- Let other projects / containers run on docker. They will work perfectly fine with a project you're working on.
|
||||
|
||||
## LISENCE
|
||||
|
||||
Copyright (C) HackerBay, Inc - All Rights Reserved
|
||||
Unauthorized copying of this project, via any medium is strictly prohibited
|
||||
This project is proprietary and confidential
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@ Repository for user authentication of the fyipe dashboard
|
||||
|
||||
## Stack
|
||||
|
||||
- Reactjs - UI Library
|
||||
- Redux - State managment
|
||||
- Redux Forms - Forms
|
||||
|
||||
- Reactjs - UI Library
|
||||
- Redux - State managment
|
||||
- Redux Forms - Forms
|
||||
|
||||
## Start
|
||||
|
||||
@@ -33,6 +32,6 @@ In production:
|
||||
|
||||
To run puppeteer tests for this repo, follow these steps:
|
||||
|
||||
- Start the backend server
|
||||
- Start the accounts application
|
||||
- Then run ```npm run test``` from your terminal
|
||||
- Start the backend server
|
||||
- Start the accounts application
|
||||
- Then run `npm run test` from your terminal
|
||||
|
||||
@@ -7,34 +7,34 @@ const child_process = require('child_process');
|
||||
const compression = require('compression');
|
||||
|
||||
const env = {
|
||||
REACT_APP_FYIPE_HOSTED: process.env.IS_SAAS_SERVICE,
|
||||
REACT_APP_HOST: process.env.HOST,
|
||||
REACT_APP_DASHBOARD_HOST: process.env.DASHBOARD_HOST,
|
||||
REACT_APP_BACKEND_HOST: process.env.BACKEND_HOST,
|
||||
REACT_APP_DOMAIN: process.env.DOMAIN,
|
||||
REACT_APP_STRIPE_PUBLIC_KEY: process.env.STRIPE_PUBLIC_KEY,
|
||||
REACT_APP_AMPLITUDE_PUBLIC_KEY: process.env.AMPLITUDE_PUBLIC_KEY
|
||||
}
|
||||
REACT_APP_FYIPE_HOSTED: process.env.IS_SAAS_SERVICE,
|
||||
REACT_APP_HOST: process.env.HOST,
|
||||
REACT_APP_DASHBOARD_HOST: process.env.DASHBOARD_HOST,
|
||||
REACT_APP_BACKEND_HOST: process.env.BACKEND_HOST,
|
||||
REACT_APP_DOMAIN: process.env.DOMAIN,
|
||||
REACT_APP_STRIPE_PUBLIC_KEY: process.env.STRIPE_PUBLIC_KEY,
|
||||
REACT_APP_AMPLITUDE_PUBLIC_KEY: process.env.AMPLITUDE_PUBLIC_KEY,
|
||||
};
|
||||
|
||||
fs.writeFileSync('.env', envfile.stringifySync(env));
|
||||
|
||||
child_process.execSync('react-env', {
|
||||
stdio: [0, 1, 2]
|
||||
stdio: [0, 1, 2],
|
||||
});
|
||||
|
||||
app.use(compression());
|
||||
|
||||
app.use(express.static(path.join(__dirname, 'build')));
|
||||
|
||||
app.get('/env.js', function (req, res) {
|
||||
res.sendFile(path.join(__dirname, 'public', 'env.js'));
|
||||
app.get('/env.js', function(req, res) {
|
||||
res.sendFile(path.join(__dirname, 'public', 'env.js'));
|
||||
});
|
||||
|
||||
app.get('/*', function (req, res) {
|
||||
res.sendFile(path.join(__dirname, 'build', 'index.html'));
|
||||
app.get('/*', function(req, res) {
|
||||
res.sendFile(path.join(__dirname, 'build', 'index.html'));
|
||||
});
|
||||
|
||||
const PORT = 3003
|
||||
const PORT = 3003;
|
||||
/* eslint-disable no-console */
|
||||
console.log(`This project is running on port ${PORT}`)
|
||||
app.listen(PORT);
|
||||
console.log(`This project is running on port ${PORT}`);
|
||||
app.listen(PORT);
|
||||
|
||||
@@ -1,53 +1,66 @@
|
||||
const { fork } = require('child_process')
|
||||
const { fork } = require('child_process');
|
||||
const child = fork('./lighthouseWorker');
|
||||
const Table = require('cli-table');
|
||||
const program = require('commander');
|
||||
|
||||
program
|
||||
.option('-m, --mobile', 'Run lighthouse on mobile')
|
||||
.option('-w, --web', 'Run lighthouse on the web');
|
||||
.option('-m, --mobile', 'Run lighthouse on mobile')
|
||||
.option('-w, --web', 'Run lighthouse on the web');
|
||||
program.parse(process.argv);
|
||||
|
||||
const table = new Table({
|
||||
head: ['url', 'performance', 'accessibility', 'best-practices', 'seo'],
|
||||
style: {head: ['green']},
|
||||
head: ['url', 'performance', 'accessibility', 'best-practices', 'seo'],
|
||||
style: { head: ['green'] },
|
||||
});
|
||||
|
||||
const sites = [
|
||||
'http://localhost:3003/login',
|
||||
'http://localhost:3003/register',
|
||||
'http://localhost:3003/forgot-password',
|
||||
'http://localhost:3003/user-verify/resend',
|
||||
'http://localhost:3003/change-password/wrongtoken',
|
||||
'http://localhost:3003/login',
|
||||
'http://localhost:3003/register',
|
||||
'http://localhost:3003/forgot-password',
|
||||
'http://localhost:3003/user-verify/resend',
|
||||
'http://localhost:3003/change-password/wrongtoken',
|
||||
];
|
||||
let sitesIndex = 0;
|
||||
let checksFailed = false;
|
||||
|
||||
child.on('message', function (score){
|
||||
const scores = [sites[sitesIndex - 1], score.performance, score.accessibility, score.bestPractices, score.seo];
|
||||
table.push(scores);
|
||||
if (score.performance < 50 || score.accessibility < 80 || score.bestPractices < 80 || score.seo < 80) {
|
||||
checksFailed = true;
|
||||
}
|
||||
if (sitesIndex < sites.length) {
|
||||
pages();
|
||||
} else {
|
||||
process.stdout.write(table.toString());
|
||||
process.stdout.write('\n');
|
||||
if (checksFailed) {
|
||||
process.stderr.write('Error: Some scores are below 80 please check table above.\n')
|
||||
process.exit(1);
|
||||
}
|
||||
process.exit();
|
||||
}
|
||||
child.on('message', function(score) {
|
||||
const scores = [
|
||||
sites[sitesIndex - 1],
|
||||
score.performance,
|
||||
score.accessibility,
|
||||
score.bestPractices,
|
||||
score.seo,
|
||||
];
|
||||
table.push(scores);
|
||||
if (
|
||||
score.performance < 50 ||
|
||||
score.accessibility < 80 ||
|
||||
score.bestPractices < 80 ||
|
||||
score.seo < 80
|
||||
) {
|
||||
checksFailed = true;
|
||||
}
|
||||
if (sitesIndex < sites.length) {
|
||||
pages();
|
||||
} else {
|
||||
process.stdout.write(table.toString());
|
||||
process.stdout.write('\n');
|
||||
if (checksFailed) {
|
||||
process.stderr.write(
|
||||
'Error: Some scores are below 80 please check table above.\n'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
|
||||
function pages () {
|
||||
if (program.mobile) {
|
||||
child.send({url: sites[sitesIndex], mobile: program.mobile });
|
||||
} else {
|
||||
child.send({url: sites[sitesIndex], mobile: false });
|
||||
}
|
||||
sitesIndex++
|
||||
function pages() {
|
||||
if (program.mobile) {
|
||||
child.send({ url: sites[sitesIndex], mobile: program.mobile });
|
||||
} else {
|
||||
child.send({ url: sites[sitesIndex], mobile: false });
|
||||
}
|
||||
sitesIndex++;
|
||||
}
|
||||
pages();
|
||||
|
||||
@@ -3,53 +3,65 @@ const chromeLauncher = require('chrome-launcher');
|
||||
const ora = require('ora');
|
||||
|
||||
function launchChromeAndRunLighthouse(url, flags = {}, config = null) {
|
||||
return chromeLauncher.launch(flags).then(chrome => {
|
||||
flags.port = chrome.port;
|
||||
return lighthouse(url, flags, config).then(results => {
|
||||
return chrome.kill().then(() => results)
|
||||
});
|
||||
});
|
||||
return chromeLauncher.launch(flags).then(chrome => {
|
||||
flags.port = chrome.port;
|
||||
return lighthouse(url, flags, config).then(results => {
|
||||
return chrome.kill().then(() => results);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const flags = {chromeFlags: ['--headless'], emulatedFormFactor: 'desktop'};
|
||||
const flags = { chromeFlags: ['--headless'], emulatedFormFactor: 'desktop' };
|
||||
|
||||
process.on('message', function (data) {
|
||||
if (data.mobile) flags.emulatedFormFactor = 'mobile';
|
||||
const scores = {};
|
||||
const spinner = ora(`Running lighthouse on ${data.url}`).start();
|
||||
spinner.color = 'green';
|
||||
launchChromeAndRunLighthouse(data.url, flags).then(results => {
|
||||
results.artifacts = 'ignore';
|
||||
results.reportGroups = 'ignore';
|
||||
results.timing = 'ignore';
|
||||
results.userAgent = 'ignore';
|
||||
results.lighthouseVersion = 'ignore';
|
||||
results.runWarnings = 'runWarnings';
|
||||
results.report = 'ignore';
|
||||
results.runtimeConfig = 'ignore';
|
||||
|
||||
results.lhr.userAgent = 'ignore';
|
||||
results.lhr.environment = 'ignore';
|
||||
results.lhr.configSettings = 'ignore';
|
||||
results.lhr.metrics = 'ignore';
|
||||
results.lhr.audits = 'ignore';
|
||||
results.lhr.categoryGroups = 'ignore';
|
||||
|
||||
scores.performance = Math.ceil(results.lhr.categories.performance.score * 100);
|
||||
scores.accessibility = Math.ceil(results.lhr.categories.accessibility.score * 100);
|
||||
scores.bestPractices = Math.ceil(results.lhr.categories['best-practices'].score * 100);
|
||||
scores.seo = Math.ceil(results.lhr.categories.seo.score * 100);
|
||||
if (scores.performance < 50 || scores.accessibility < 80 || scores.bestPractices < 80 || scores.seo < 80) {
|
||||
spinner.fail();
|
||||
} else {
|
||||
spinner.succeed();
|
||||
}
|
||||
process.send(scores);
|
||||
return scores;
|
||||
})
|
||||
.catch(err => {
|
||||
/* eslint-disable no-console */
|
||||
console.log(err)
|
||||
process.exit(1);
|
||||
});
|
||||
process.on('message', function(data) {
|
||||
if (data.mobile) flags.emulatedFormFactor = 'mobile';
|
||||
const scores = {};
|
||||
const spinner = ora(`Running lighthouse on ${data.url}`).start();
|
||||
spinner.color = 'green';
|
||||
launchChromeAndRunLighthouse(data.url, flags)
|
||||
.then(results => {
|
||||
results.artifacts = 'ignore';
|
||||
results.reportGroups = 'ignore';
|
||||
results.timing = 'ignore';
|
||||
results.userAgent = 'ignore';
|
||||
results.lighthouseVersion = 'ignore';
|
||||
results.runWarnings = 'runWarnings';
|
||||
results.report = 'ignore';
|
||||
results.runtimeConfig = 'ignore';
|
||||
|
||||
results.lhr.userAgent = 'ignore';
|
||||
results.lhr.environment = 'ignore';
|
||||
results.lhr.configSettings = 'ignore';
|
||||
results.lhr.metrics = 'ignore';
|
||||
results.lhr.audits = 'ignore';
|
||||
results.lhr.categoryGroups = 'ignore';
|
||||
|
||||
scores.performance = Math.ceil(
|
||||
results.lhr.categories.performance.score * 100
|
||||
);
|
||||
scores.accessibility = Math.ceil(
|
||||
results.lhr.categories.accessibility.score * 100
|
||||
);
|
||||
scores.bestPractices = Math.ceil(
|
||||
results.lhr.categories['best-practices'].score * 100
|
||||
);
|
||||
scores.seo = Math.ceil(results.lhr.categories.seo.score * 100);
|
||||
if (
|
||||
scores.performance < 50 ||
|
||||
scores.accessibility < 80 ||
|
||||
scores.bestPractices < 80 ||
|
||||
scores.seo < 80
|
||||
) {
|
||||
spinner.fail();
|
||||
} else {
|
||||
spinner.succeed();
|
||||
}
|
||||
process.send(scores);
|
||||
return scores;
|
||||
})
|
||||
.catch(err => {
|
||||
/* eslint-disable no-console */
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
});
|
||||
});
|
||||
|
||||
39600
accounts/package-lock.json
generated
39600
accounts/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,91 +1,91 @@
|
||||
{
|
||||
"name": "fyipe-accounts",
|
||||
"version": "3.0.1891",
|
||||
"private": true,
|
||||
"homepage": "/",
|
||||
"dependencies": {
|
||||
"@beam-australia/react-env": "^2.1.2",
|
||||
"amplitude-js": "^5.8.0",
|
||||
"axios": "^0.18.0",
|
||||
"browserslist": "^4.6.1",
|
||||
"card-validator": "^4.3.0",
|
||||
"cli-table": "^0.3.1",
|
||||
"compression": "^1.7.4",
|
||||
"envfile": "^3.0.0",
|
||||
"express": "^4.16.4",
|
||||
"faker": "^4.1.0",
|
||||
"file-saver": "^2.0.1",
|
||||
"history": "^4.7.2",
|
||||
"jest": "^24.7.1",
|
||||
"loadable-components": "^2.2.3",
|
||||
"prop-types": "^15.6.1",
|
||||
"puppeteer": "^1.19.0",
|
||||
"query-string": "^5.1.1",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-frontload": "^1.0.3",
|
||||
"react-ga": "^2.5.3",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-router-redux": "^4.0.8",
|
||||
"react-scripts": "^3.0.1",
|
||||
"react-stripe-elements": "^1.6.0",
|
||||
"redux": "^3.7.2",
|
||||
"redux-form": "^7.3.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"sane-email-validation": "^1.1.0",
|
||||
"should": "^13.2.3",
|
||||
"universal-cookie": "^4.0.0",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"fix-lint": "eslint . --fix",
|
||||
"dev": "PORT=3003 react-scripts start",
|
||||
"build": "react-scripts build && npm run build-sw && npm run clean-cra-sw",
|
||||
"clean-cra-sw": "rm -f build/precache-manifest.*.js && rm -f build/service-worker.js",
|
||||
"test": "jest --runInBand src/test",
|
||||
"start": "node index.js",
|
||||
"audit": "npm-audit-ci-wrapper --threshold=high",
|
||||
"light-house": "node lighthouse.js --web",
|
||||
"light-house-mobile": "node lighthouse.js --mobile",
|
||||
"build-sw": "node ./src/sw-build.js",
|
||||
"dep-check": "depcheck ./ --skip-missing=true --ignores='eslint,babel-*,browserslist,loadable-components,@beam-australia/react-env'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"chrome-launcher": "^0.12.0",
|
||||
"commander": "^4.0.1",
|
||||
"depcheck": "^0.9.2",
|
||||
"eslint-plugin-react": "^7.18.3",
|
||||
"lighthouse": "^5.6.0",
|
||||
"npm-audit-ci-wrapper": "^2.4.3",
|
||||
"ora": "^4.0.3",
|
||||
"redux-logger": "^3.0.6",
|
||||
"workbox-build": "^4.3.1"
|
||||
},
|
||||
"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"
|
||||
]
|
||||
}
|
||||
"name": "fyipe-accounts",
|
||||
"version": "3.0.1891",
|
||||
"private": true,
|
||||
"homepage": "/",
|
||||
"dependencies": {
|
||||
"@beam-australia/react-env": "^2.1.2",
|
||||
"amplitude-js": "^5.8.0",
|
||||
"axios": "^0.18.0",
|
||||
"browserslist": "^4.6.1",
|
||||
"card-validator": "^4.3.0",
|
||||
"cli-table": "^0.3.1",
|
||||
"compression": "^1.7.4",
|
||||
"envfile": "^3.0.0",
|
||||
"express": "^4.16.4",
|
||||
"faker": "^4.1.0",
|
||||
"file-saver": "^2.0.1",
|
||||
"history": "^4.7.2",
|
||||
"jest": "^24.7.1",
|
||||
"loadable-components": "^2.2.3",
|
||||
"prop-types": "^15.6.1",
|
||||
"puppeteer": "^1.19.0",
|
||||
"query-string": "^5.1.1",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-frontload": "^1.0.3",
|
||||
"react-ga": "^2.5.3",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-router-redux": "^4.0.8",
|
||||
"react-scripts": "^3.0.1",
|
||||
"react-stripe-elements": "^1.6.0",
|
||||
"redux": "^3.7.2",
|
||||
"redux-form": "^7.3.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"sane-email-validation": "^1.1.0",
|
||||
"should": "^13.2.3",
|
||||
"universal-cookie": "^4.0.0",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"fix-lint": "eslint . --fix",
|
||||
"dev": "PORT=3003 react-scripts start",
|
||||
"build": "react-scripts build && npm run build-sw && npm run clean-cra-sw",
|
||||
"clean-cra-sw": "rm -f build/precache-manifest.*.js && rm -f build/service-worker.js",
|
||||
"test": "jest --runInBand src/test",
|
||||
"start": "node index.js",
|
||||
"audit": "npm-audit-ci-wrapper --threshold=high",
|
||||
"light-house": "node lighthouse.js --web",
|
||||
"light-house-mobile": "node lighthouse.js --mobile",
|
||||
"build-sw": "node ./src/sw-build.js",
|
||||
"dep-check": "depcheck ./ --skip-missing=true --ignores='eslint,babel-*,browserslist,loadable-components,@beam-australia/react-env'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"chrome-launcher": "^0.12.0",
|
||||
"commander": "^4.0.1",
|
||||
"depcheck": "^0.9.2",
|
||||
"eslint-plugin-react": "^7.18.3",
|
||||
"lighthouse": "^5.6.0",
|
||||
"npm-audit-ci-wrapper": "^2.4.3",
|
||||
"ora": "^4.0.3",
|
||||
"redux-logger": "^3.0.6",
|
||||
"workbox-build": "^4.3.1"
|
||||
},
|
||||
"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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,76 +11,76 @@ import ReactGA from 'react-ga';
|
||||
import Cookies from 'universal-cookie';
|
||||
import { saveStatusPage } from './actions/login';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const cookies = new Cookies();
|
||||
const logoutData = cookies.get('logoutData');
|
||||
|
||||
if (!isServer) {
|
||||
history.listen(location => {
|
||||
ReactGA.set({ page: location.pathname });
|
||||
ReactGA.pageview(location.pathname);
|
||||
});
|
||||
history.listen(location => {
|
||||
ReactGA.set({ page: location.pathname });
|
||||
ReactGA.pageview(location.pathname);
|
||||
});
|
||||
}
|
||||
|
||||
const statusPageLogin = queryString.parse(window.location.search).statusPage;
|
||||
const statusPageURL = queryString.parse(window.location.search).statusPageURL;
|
||||
|
||||
if (logoutData && User.isLoggedIn()) {
|
||||
cookies.remove('logoutData', { domain: DOMAIN_URL });
|
||||
localStorage.clear();
|
||||
cookies.remove('logoutData', { domain: DOMAIN_URL });
|
||||
localStorage.clear();
|
||||
} else if (!statusPageLogin && !logoutData && User.isLoggedIn()) {
|
||||
window.location = DASHBOARD_URL;
|
||||
window.location = DASHBOARD_URL;
|
||||
}
|
||||
|
||||
const App = (props) => {
|
||||
if (statusPageLogin && statusPageURL) {
|
||||
props.saveStatusPage({
|
||||
statusPageLogin,
|
||||
statusPageURL
|
||||
})
|
||||
}
|
||||
const App = props => {
|
||||
if (statusPageLogin && statusPageURL) {
|
||||
props.saveStatusPage({
|
||||
statusPageLogin,
|
||||
statusPageURL,
|
||||
});
|
||||
}
|
||||
|
||||
return (<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>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<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';
|
||||
|
||||
|
||||
App.propTypes = {
|
||||
saveStatusPage: PropTypes.func.isRequired,
|
||||
}
|
||||
saveStatusPage: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return state.login;
|
||||
return state.login;
|
||||
}
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators({ saveStatusPage }, dispatch)
|
||||
return bindActionCreators({ saveStatusPage }, dispatch);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(App);
|
||||
|
||||
@@ -1,61 +1,57 @@
|
||||
import {
|
||||
postApi
|
||||
} from '../api';
|
||||
import * as types from '../constants/changePassword'
|
||||
import errors from '../errors'
|
||||
|
||||
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
|
||||
};
|
||||
return {
|
||||
type: types.CHANGEPASSWORD_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function changePasswordError(error) {
|
||||
return {
|
||||
type: types.CHANGEPASSWORD_FAILED,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.CHANGEPASSWORD_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function changePasswordSuccess(values) {
|
||||
|
||||
return {
|
||||
type: types.CHANGEPASSWORD_SUCCESS,
|
||||
payload: values
|
||||
};
|
||||
return {
|
||||
type: types.CHANGEPASSWORD_SUCCESS,
|
||||
payload: values,
|
||||
};
|
||||
}
|
||||
|
||||
export const resetChangePassword = () => {
|
||||
return {
|
||||
type: types.RESET_CHANGEPASSWORD,
|
||||
};
|
||||
return {
|
||||
type: types.RESET_CHANGEPASSWORD,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to register a user.
|
||||
export function changePassword(values) {
|
||||
return function (dispatch) {
|
||||
return function(dispatch) {
|
||||
const promise = postApi('user/reset-password', values);
|
||||
dispatch(changePasswordRequest(promise));
|
||||
|
||||
const 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)));
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
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)));
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
|
||||
import { postApi } from '../api';
|
||||
import * as types from '../constants/login';
|
||||
import {
|
||||
postApi
|
||||
} from '../api';
|
||||
import * as types from '../constants/login'
|
||||
import { User, DASHBOARD_URL, DOMAIN_URL, ADMIN_DASHBOARD_URL } from '../config.js';
|
||||
import errors from '../errors'
|
||||
User,
|
||||
DASHBOARD_URL,
|
||||
DOMAIN_URL,
|
||||
ADMIN_DASHBOARD_URL,
|
||||
} from '../config.js';
|
||||
import errors from '../errors';
|
||||
import { getQueryVar } from '../config';
|
||||
import { resendToken } from './resendToken';
|
||||
import Cookies from 'universal-cookie';
|
||||
@@ -14,205 +16,219 @@ import store from '../store';
|
||||
// process and we need actions for each of them
|
||||
|
||||
export function loginRequest(promise) {
|
||||
return {
|
||||
type: types.LOGIN_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
return {
|
||||
type: types.LOGIN_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function loginError(error) {
|
||||
return {
|
||||
type: types.LOGIN_FAILED,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.LOGIN_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function loginSuccess(user) {
|
||||
//save user session details.
|
||||
if (!user.id) {
|
||||
User.setEmail(user.email)
|
||||
return {
|
||||
type: types.LOGIN_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
}
|
||||
//save user session details.
|
||||
if (!user.id) {
|
||||
User.setEmail(user.email);
|
||||
return {
|
||||
type: types.LOGIN_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
}
|
||||
|
||||
const state = store.getState();
|
||||
const { statusPageLogin, statusPageURL } = state.login;
|
||||
if (statusPageLogin) {
|
||||
const newURL = `${statusPageURL}?userId=${user.id}&accessToken=${user.tokens.jwtAccessToken}`;
|
||||
return window.location = newURL;
|
||||
}
|
||||
User.setUserId(user.id);
|
||||
User.setAccessToken(user.tokens.jwtAccessToken);
|
||||
User.setEmail(user.email);
|
||||
User.setName(user.name);
|
||||
User.setCardRegistered(user.cardRegistered);
|
||||
const state = store.getState();
|
||||
const { statusPageLogin, statusPageURL } = state.login;
|
||||
if (statusPageLogin) {
|
||||
const newURL = `${statusPageURL}?userId=${user.id}&accessToken=${user.tokens.jwtAccessToken}`;
|
||||
return (window.location = newURL);
|
||||
}
|
||||
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
|
||||
let cookies = new Cookies();
|
||||
let userData = user;
|
||||
cookies.set('data', userData, { path: '/', maxAge: 30, domain: DOMAIN_URL });
|
||||
//share localStorage with dashboard app
|
||||
let cookies = new Cookies();
|
||||
let userData = user;
|
||||
cookies.set('data', userData, {
|
||||
path: '/',
|
||||
maxAge: 30,
|
||||
domain: DOMAIN_URL,
|
||||
});
|
||||
|
||||
if(user.role === 'master-admin'){
|
||||
//share localStorage with admin dashboard app
|
||||
cookies = new Cookies();
|
||||
userData = user;
|
||||
cookies.set('admin-data', userData, { path: '/', maxAge: 30, domain: DOMAIN_URL });
|
||||
}
|
||||
if (user.role === 'master-admin') {
|
||||
//share localStorage with admin dashboard app
|
||||
cookies = new Cookies();
|
||||
userData = user;
|
||||
cookies.set('admin-data', userData, {
|
||||
path: '/',
|
||||
maxAge: 30,
|
||||
domain: DOMAIN_URL,
|
||||
});
|
||||
}
|
||||
|
||||
if (user.redirect){
|
||||
return window.location = `${user.redirect}?accessToken=${user.tokens.jwtAccessToken}`;
|
||||
}else if(user.role === 'master-admin'){
|
||||
window.location = ADMIN_DASHBOARD_URL
|
||||
}else{
|
||||
window.location = DASHBOARD_URL
|
||||
}
|
||||
|
||||
return {
|
||||
type: types.LOGIN_SUCCESS,
|
||||
payload: user
|
||||
};
|
||||
if (user.redirect) {
|
||||
return (window.location = `${user.redirect}?accessToken=${user.tokens.jwtAccessToken}`);
|
||||
} else if (user.role === 'master-admin') {
|
||||
window.location = ADMIN_DASHBOARD_URL;
|
||||
} else {
|
||||
window.location = DASHBOARD_URL;
|
||||
}
|
||||
|
||||
return {
|
||||
type: types.LOGIN_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
}
|
||||
|
||||
export const resetLogin = () => {
|
||||
return {
|
||||
type: types.RESET_LOGIN,
|
||||
};
|
||||
return {
|
||||
type: types.RESET_LOGIN,
|
||||
};
|
||||
};
|
||||
|
||||
export function verifyTokenRequest(promise) {
|
||||
return {
|
||||
type: types.AUTH_VERIFICATION_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
return {
|
||||
type: types.AUTH_VERIFICATION_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function verifyTokenError(error) {
|
||||
return {
|
||||
type: types.AUTH_VERIFICATION_FAILED,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.AUTH_VERIFICATION_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
// Calls the API to register a user.
|
||||
export function loginUser(values) {
|
||||
const initialUrl = User.initialUrl();
|
||||
const redirect = getQueryVar('redirectTo', initialUrl);
|
||||
if(redirect) values.redirect = redirect;
|
||||
return function (dispatch) {
|
||||
const initialUrl = User.initialUrl();
|
||||
const redirect = getQueryVar('redirectTo', initialUrl);
|
||||
if (redirect) values.redirect = redirect;
|
||||
return function(dispatch) {
|
||||
const promise = postApi('user/login', values);
|
||||
dispatch(loginRequest(promise));
|
||||
|
||||
const promise = postApi('user/login', values);
|
||||
dispatch(loginRequest(promise));
|
||||
|
||||
promise.then(function (user) {
|
||||
dispatch(loginSuccess(user.data));
|
||||
}, function (error) {
|
||||
if(error.message === 'Verify your email first.'){
|
||||
dispatch(resendToken(values));
|
||||
}
|
||||
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;
|
||||
};
|
||||
promise.then(
|
||||
function(user) {
|
||||
dispatch(loginSuccess(user.data));
|
||||
},
|
||||
function(error) {
|
||||
if (error.message === 'Verify your email first.') {
|
||||
dispatch(resendToken(values));
|
||||
}
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
// Calls the API to verify a user token and log them in.
|
||||
export function verifyAuthToken(values) {
|
||||
const initialUrl = User.initialUrl();
|
||||
const redirect = getQueryVar('redirectTo', initialUrl);
|
||||
if(redirect) values.redirect = redirect;
|
||||
const email = User.getEmail();
|
||||
values.email = email;
|
||||
return function (dispatch) {
|
||||
const promise = postApi('user/totp/verifyToken', values);
|
||||
dispatch(verifyTokenRequest(promise));
|
||||
const initialUrl = User.initialUrl();
|
||||
const redirect = getQueryVar('redirectTo', initialUrl);
|
||||
if (redirect) values.redirect = redirect;
|
||||
const email = User.getEmail();
|
||||
values.email = email;
|
||||
return function(dispatch) {
|
||||
const promise = postApi('user/totp/verifyToken', values);
|
||||
dispatch(verifyTokenRequest(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(verifyTokenError(errors(error)));
|
||||
});
|
||||
return 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(verifyTokenError(errors(error)));
|
||||
}
|
||||
);
|
||||
return promise;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Use backup code to login a user.
|
||||
|
||||
export const resetBackupCodeLogin = () => {
|
||||
return {
|
||||
type: types.RESET_BACKUP_CODE_VERIFICATION,
|
||||
};
|
||||
return {
|
||||
type: types.RESET_BACKUP_CODE_VERIFICATION,
|
||||
};
|
||||
};
|
||||
|
||||
export function useBackupCodeRequest(promise) {
|
||||
return {
|
||||
type: types.BACKUP_CODE_VERIFICATION_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
return {
|
||||
type: types.BACKUP_CODE_VERIFICATION_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function useBackupCodeError(error) {
|
||||
return {
|
||||
type: types.BACKUP_CODE_VERIFICATION_FAILED,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.BACKUP_CODE_VERIFICATION_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function verifyBackupCode(values) {
|
||||
const initialUrl = User.initialUrl();
|
||||
const redirect = getQueryVar('redirectTo', initialUrl);
|
||||
if(redirect) values.redirect = redirect;
|
||||
const email = User.getEmail();
|
||||
values.email = email;
|
||||
return function (dispatch) {
|
||||
const promise = postApi('user/verify/backupCode', values);
|
||||
dispatch(useBackupCodeRequest(promise));
|
||||
const initialUrl = User.initialUrl();
|
||||
const redirect = getQueryVar('redirectTo', initialUrl);
|
||||
if (redirect) values.redirect = redirect;
|
||||
const email = User.getEmail();
|
||||
values.email = email;
|
||||
return function(dispatch) {
|
||||
const promise = postApi('user/verify/backupCode', values);
|
||||
dispatch(useBackupCodeRequest(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(useBackupCodeError(errors(error)));
|
||||
});
|
||||
return 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(useBackupCodeError(errors(error)));
|
||||
}
|
||||
);
|
||||
return promise;
|
||||
};
|
||||
}
|
||||
|
||||
export function saveStatusPage(data) {
|
||||
return {
|
||||
type: types.SAVE_STATUS_PAGE,
|
||||
payload: data
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SAVE_STATUS_PAGE,
|
||||
payload: data,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import * as types from '../constants/modal'
|
||||
import * as types from '../constants/modal';
|
||||
|
||||
export const openModal = function(obj) {
|
||||
return {
|
||||
type: types.OPEN_MODAL,
|
||||
payload: obj
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.OPEN_MODAL,
|
||||
payload: obj,
|
||||
};
|
||||
};
|
||||
export const closeModal = function(obj) {
|
||||
return {
|
||||
type: types.CLOSE_MODAL,
|
||||
payload: obj
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
type: types.CLOSE_MODAL,
|
||||
payload: obj,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,229 +1,226 @@
|
||||
import {
|
||||
postApi
|
||||
} from '../api';
|
||||
import * as types from '../constants/register'
|
||||
import errors from '../errors'
|
||||
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
|
||||
};
|
||||
return {
|
||||
type: types.SIGNUP_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function saveUserState(values) {
|
||||
return {
|
||||
type: types.SAVE_USER_STATE,
|
||||
payload: values
|
||||
};
|
||||
return {
|
||||
type: types.SAVE_USER_STATE,
|
||||
payload: values,
|
||||
};
|
||||
}
|
||||
|
||||
export function savePlanId(planId) {
|
||||
return {
|
||||
type: types.SAVE_PLAN_ID,
|
||||
payload: planId
|
||||
};
|
||||
return {
|
||||
type: types.SAVE_PLAN_ID,
|
||||
payload: planId,
|
||||
};
|
||||
}
|
||||
|
||||
export function saveCardState(values) {
|
||||
return {
|
||||
type: types.SAVE_CARD_STATE,
|
||||
payload: values
|
||||
};
|
||||
return {
|
||||
type: types.SAVE_CARD_STATE,
|
||||
payload: values,
|
||||
};
|
||||
}
|
||||
|
||||
export function saveCompanyState(values) {
|
||||
return {
|
||||
type: types.SAVE_COMPANY_STATE,
|
||||
payload: values
|
||||
};
|
||||
return {
|
||||
type: types.SAVE_COMPANY_STATE,
|
||||
payload: values,
|
||||
};
|
||||
}
|
||||
|
||||
export function signUpRequest(promise) {
|
||||
return {
|
||||
type: types.SIGNUP_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
return {
|
||||
type: types.SIGNUP_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function signUpReset() {
|
||||
return {
|
||||
type: types.RESET_SIGNUP,
|
||||
};
|
||||
return {
|
||||
type: types.RESET_SIGNUP,
|
||||
};
|
||||
}
|
||||
|
||||
export function signupSuccess(user) {
|
||||
return {
|
||||
type: types.SIGNUP_SUCCESS,
|
||||
payload: user
|
||||
}
|
||||
return {
|
||||
type: types.SIGNUP_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
}
|
||||
|
||||
export const resetSignup = () => {
|
||||
return {
|
||||
type: types.RESET_SIGNUP,
|
||||
};
|
||||
return {
|
||||
type: types.RESET_SIGNUP,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to register a user.
|
||||
export function signupUser(values) {
|
||||
return function (dispatch) {
|
||||
const 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;
|
||||
};
|
||||
return function(dispatch) {
|
||||
const 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,
|
||||
};
|
||||
return {
|
||||
type: types.SIGNUP_STEP_INC,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
//np payload for inc and dec action creators.
|
||||
export const skipCardStep = () => {
|
||||
return {
|
||||
type: types.SKIP_CARD_STEP,
|
||||
};
|
||||
return {
|
||||
type: types.SKIP_CARD_STEP,
|
||||
};
|
||||
};
|
||||
|
||||
export const decrementStep = () => {
|
||||
return {
|
||||
type: types.SIGNUP_STEP_DEC,
|
||||
};
|
||||
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
|
||||
};
|
||||
return {
|
||||
type: types.IS_USER_INVITED_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function isUserInvitedReset() {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
};
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
};
|
||||
}
|
||||
|
||||
export function isUserInvitedError(error) {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function isUserInvitedSuccess(data) {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_SUCCESS,
|
||||
payload: data
|
||||
};
|
||||
return {
|
||||
type: types.IS_USER_INVITED_SUCCESS,
|
||||
payload: data,
|
||||
};
|
||||
}
|
||||
|
||||
export const resetIsUserInvited = () => {
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
};
|
||||
return {
|
||||
type: types.IS_USER_INVITED_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to register a user.
|
||||
export function isUserInvited(values) {
|
||||
return function (dispatch) {
|
||||
const 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 function(dispatch) {
|
||||
const 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;
|
||||
};
|
||||
return promise;
|
||||
};
|
||||
}
|
||||
|
||||
export function addCardRequest(promise) {
|
||||
return {
|
||||
type: types.ADD_CARD_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
return {
|
||||
type: types.ADD_CARD_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function addCardFailed(error) {
|
||||
return {
|
||||
type: types.ADD_CARD_FAILED,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.ADD_CARD_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function addCardSuccess(card) {
|
||||
return {
|
||||
type: types.ADD_CARD_SUCCESS,
|
||||
payload: card
|
||||
};
|
||||
return {
|
||||
type: types.ADD_CARD_SUCCESS,
|
||||
payload: card,
|
||||
};
|
||||
}
|
||||
|
||||
export function addCard(data) {
|
||||
return function(dispatch) {
|
||||
const promise = postApi('stripe/checkCard', data);
|
||||
|
||||
return function (dispatch) {
|
||||
const promise = postApi('stripe/checkCard', data)
|
||||
dispatch(addCardRequest(promise));
|
||||
|
||||
dispatch(addCardRequest(promise));
|
||||
|
||||
promise.then(function (card) {
|
||||
dispatch(addCardSuccess(card.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(addCardFailed(error));
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
promise.then(
|
||||
function(card) {
|
||||
dispatch(addCardSuccess(card.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(addCardFailed(error));
|
||||
}
|
||||
);
|
||||
return promise;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,51 +1,50 @@
|
||||
import { postApi } from '../api';
|
||||
import * as types from '../constants/resendToken'
|
||||
import errors from '../errors'
|
||||
import * as types from '../constants/resendToken';
|
||||
import errors from '../errors';
|
||||
|
||||
export function resendTokenRequest(promise) {
|
||||
return {
|
||||
type: types.RESENDTOKEN_REQUEST,
|
||||
payload: promise
|
||||
};
|
||||
return {
|
||||
type: types.RESENDTOKEN_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function resendTokenError(error) {
|
||||
return {
|
||||
type: types.RESENDTOKEN_FAILED,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.RESENDTOKEN_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function resendTokenSuccess(data) {
|
||||
|
||||
return {
|
||||
type: types.RESENDTOKEN_SUCCESS,
|
||||
payload: data
|
||||
};
|
||||
return {
|
||||
type: types.RESENDTOKEN_SUCCESS,
|
||||
payload: data,
|
||||
};
|
||||
}
|
||||
|
||||
export function resendToken(values) {
|
||||
return function(dispatch){
|
||||
return function(dispatch) {
|
||||
const promise = postApi('user/resend', values);
|
||||
dispatch(resendTokenRequest(promise));
|
||||
|
||||
const 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)));
|
||||
});
|
||||
|
||||
};
|
||||
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)));
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,60 +1,59 @@
|
||||
import { postApi } from '../api';
|
||||
import * as types from '../constants/resetPassword'
|
||||
import errors from '../errors'
|
||||
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
|
||||
};
|
||||
return {
|
||||
type: types.PASSWORDRESET_REQUEST,
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function resetPasswordError(error) {
|
||||
return {
|
||||
type: types.PASSWORDRESET_FAILED,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.PASSWORDRESET_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function resetPasswordSuccess(data) {
|
||||
|
||||
return {
|
||||
type: types.PASSWORDRESET_SUCCESS,
|
||||
payload: data
|
||||
};
|
||||
return {
|
||||
type: types.PASSWORDRESET_SUCCESS,
|
||||
payload: data,
|
||||
};
|
||||
}
|
||||
|
||||
export const resetResetPassword = () => {
|
||||
return {
|
||||
type: types.RESET_PASSWORDRESET,
|
||||
};
|
||||
return {
|
||||
type: types.RESET_PASSWORDRESET,
|
||||
};
|
||||
};
|
||||
|
||||
export function resetPassword(values) {
|
||||
return function(dispatch){
|
||||
return function(dispatch) {
|
||||
const promise = postApi('user/forgot-password', values);
|
||||
dispatch(resetPasswordRequest(promise));
|
||||
|
||||
const 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)));
|
||||
});
|
||||
|
||||
};
|
||||
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)));
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,15 +3,15 @@ const { env } = require('./config');
|
||||
|
||||
amplitude.init(env('AMPLITUDE_PUBLIC_KEY'), null, { includeReferrer: true });
|
||||
|
||||
export const setUserId = function (userId) {
|
||||
export const setUserId = function(userId) {
|
||||
amplitude.setUserId(userId);
|
||||
};
|
||||
export const identify = function(userId) {
|
||||
amplitude.identify(userId);
|
||||
}
|
||||
};
|
||||
export const setUserProperties = function(properties) {
|
||||
amplitude.setUserProperties(properties);
|
||||
}
|
||||
export const logEvent = function (event, data) {
|
||||
};
|
||||
export const logEvent = function(event, data) {
|
||||
amplitude.logEvent(event, data);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import axios from 'axios';
|
||||
import {
|
||||
API_URL
|
||||
} from './config';
|
||||
import {
|
||||
User
|
||||
} from './config';
|
||||
import { API_URL } from './config';
|
||||
import { User } from './config';
|
||||
import { history } from './store';
|
||||
const baseURL = API_URL;
|
||||
|
||||
@@ -12,27 +8,25 @@ const Q = require('q');
|
||||
|
||||
const headers = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
};
|
||||
|
||||
|
||||
|
||||
export function postApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken();
|
||||
const deffered = Q.defer();
|
||||
|
||||
axios({
|
||||
method: 'POST',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
data,
|
||||
})
|
||||
.then(function (response) {
|
||||
.then(function(response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch(function(error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
@@ -49,17 +43,17 @@ export function postApi(url, data) {
|
||||
|
||||
export function getApi(url) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken();
|
||||
const deffered = Q.defer();
|
||||
axios({
|
||||
method: 'GET',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers
|
||||
headers,
|
||||
})
|
||||
.then(function (response) {
|
||||
.then(function(response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch(function(error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
@@ -75,21 +69,20 @@ export function getApi(url) {
|
||||
return deffered.promise;
|
||||
}
|
||||
|
||||
|
||||
export function putApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken();
|
||||
const deffered = Q.defer();
|
||||
axios({
|
||||
method: 'PUT',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
data,
|
||||
})
|
||||
.then(function (response) {
|
||||
.then(function(response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch(function(error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
@@ -107,18 +100,18 @@ export function putApi(url, data) {
|
||||
|
||||
export function deleteApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken();
|
||||
const deffered = Q.defer();
|
||||
axios({
|
||||
method: 'DELETE',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
data,
|
||||
})
|
||||
.then(function (response) {
|
||||
.then(function(response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch(function(error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
|
||||
@@ -1,35 +1,40 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
|
||||
class NotFound extends Component {
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
<div className="db-World-root" >
|
||||
|
||||
<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
|
||||
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'
|
||||
|
||||
NotFound.displayName = 'NotFound';
|
||||
|
||||
export default NotFound;
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
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="request-reset-step step">
|
||||
<div className="title">
|
||||
<h2 style={{ marginBottom: 0 }}>
|
||||
{props.title}
|
||||
</h2>
|
||||
<h2 style={{ marginBottom: 0 }}>{props.title}</h2>
|
||||
</div>
|
||||
<p className="message">
|
||||
{props.message}
|
||||
@@ -18,13 +16,13 @@ export default function MessageBox(props) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
MessageBox.displayName = 'MessageBox'
|
||||
MessageBox.displayName = 'MessageBox';
|
||||
|
||||
MessageBox.propTypes = {
|
||||
title: PropTypes.string,
|
||||
message: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
}
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
@@ -1,43 +1,49 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const composableComponent = (ComposedComponent) => {
|
||||
const composableComponent = ComposedComponent => {
|
||||
class Modal extends Component {
|
||||
constructor(props){
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.onClose = this.onClose.bind(this);
|
||||
this.onConfirm = this.onConfirm.bind(this);
|
||||
}
|
||||
onClose =(value)=> {
|
||||
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)=> {
|
||||
};
|
||||
onConfirm = value => {
|
||||
const _this = this;
|
||||
if (this.props.item.onConfirm) {
|
||||
this.props.item.onConfirm(value)
|
||||
.then(() => _this.props.onClose(_this.props.item),
|
||||
()=> {})
|
||||
this.props.item.onConfirm(value).then(
|
||||
() => _this.props.onClose(_this.props.item),
|
||||
() => {}
|
||||
);
|
||||
} else {
|
||||
this.props.onClose(this.props.item)
|
||||
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'};
|
||||
const modalContainerStyle = {
|
||||
overflowX: 'auto',
|
||||
overflowY: 'scroll',
|
||||
display: 'block',
|
||||
top: '0px',
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={mainClass}
|
||||
style={{
|
||||
zIndex: (zIndex + 1) * 10000
|
||||
zIndex: (zIndex + 1) * 10000,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
@@ -47,12 +53,17 @@ const composableComponent = (ComposedComponent) => {
|
||||
opacity: 1,
|
||||
transform: 'none',
|
||||
display: 'block',
|
||||
pointerEvents: 'auto'
|
||||
pointerEvents: 'auto',
|
||||
}}
|
||||
>
|
||||
|
||||
<div className="modal_container" style={modalContainerStyle}>
|
||||
<ComposedComponent closeThisDialog={this.onClose} confirmThisDialog={this.onConfirm} />
|
||||
<div
|
||||
className="modal_container"
|
||||
style={modalContainerStyle}
|
||||
>
|
||||
<ComposedComponent
|
||||
closeThisDialog={this.onClose}
|
||||
confirmThisDialog={this.onConfirm}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,15 +73,14 @@ const composableComponent = (ComposedComponent) => {
|
||||
Modal.propTypes = {
|
||||
onConfirm: PropTypes.func,
|
||||
item: PropTypes.object.isRequired,
|
||||
onClose:PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
extraClasses: PropTypes.string,
|
||||
zIndex: PropTypes.number.isRequired
|
||||
}
|
||||
zIndex: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
Modal.displayName = 'Modal'
|
||||
Modal.displayName = 'Modal';
|
||||
|
||||
return Modal;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default composableComponent;
|
||||
export default composableComponent;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,132 +1,179 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { Validate } from '../../config';
|
||||
import { ButtonSpinner } from '../basic/Loader.js';
|
||||
import { changePasswordError, changePasswordSuccess, changePassword, resetChangePassword } from '../../actions/changePassword';
|
||||
import {
|
||||
changePasswordError,
|
||||
changePasswordSuccess,
|
||||
changePassword,
|
||||
resetChangePassword,
|
||||
} from '../../actions/changePassword';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { RenderField } from '../basic/RenderField';
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const errorStyle = {
|
||||
color: '#c23d4b'
|
||||
}
|
||||
color: '#c23d4b',
|
||||
};
|
||||
export class ChangePasswordForm extends Component {
|
||||
submitForm = values => {
|
||||
values.token = this.props.token || '';
|
||||
this.props.changePassword(values);
|
||||
};
|
||||
|
||||
submitForm =(values)=> {
|
||||
values.token = this.props.token || '';
|
||||
this.props.changePassword(values);
|
||||
}
|
||||
render() {
|
||||
const changePasswordStateError = this.props.changePasswordState.error;
|
||||
let header;
|
||||
if (changePasswordStateError) {
|
||||
header = <span style={errorStyle}>{changePasswordStateError}</span>;
|
||||
} else {
|
||||
header = <span>Reset Password</span>;
|
||||
}
|
||||
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">
|
||||
<div className="title">
|
||||
<h2>{header}</h2>
|
||||
</div>
|
||||
|
||||
render() {
|
||||
const changePasswordStateError = this.props.changePasswordState.error;
|
||||
let header;
|
||||
if (changePasswordStateError) {
|
||||
header = <span style={errorStyle}>{changePasswordStateError}</span>
|
||||
} else {
|
||||
header = <span>Reset Password</span>
|
||||
}
|
||||
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" >
|
||||
<div className="title">
|
||||
<h2>
|
||||
{header}
|
||||
</h2>
|
||||
</div>
|
||||
<p className="error-message hidden" />
|
||||
|
||||
<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">
|
||||
{' '}
|
||||
Please enter a new password to continue
|
||||
</p>
|
||||
)}
|
||||
|
||||
|
||||
{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"> Please enter a new password to continue</p>}
|
||||
|
||||
|
||||
{!this.props.changePasswordState.success && <div> <p className="text">
|
||||
<span id="passwordField">
|
||||
<label htmlFor="password"> New Password </label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="password"
|
||||
name="password"
|
||||
id="password"
|
||||
placeholder="Password"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span id="confirmPasswordField">
|
||||
<label htmlFor="confirmPassword"> Confirm New 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 && <ButtonSpinner />}
|
||||
</button>
|
||||
</p> </div>}
|
||||
{!this.props.changePasswordState.success && (
|
||||
<div>
|
||||
{' '}
|
||||
<p className="text">
|
||||
<span id="passwordField">
|
||||
<label htmlFor="password">
|
||||
{' '}
|
||||
New Password{' '}
|
||||
</label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="password"
|
||||
name="password"
|
||||
id="password"
|
||||
placeholder="Password"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text">
|
||||
<span id="confirmPasswordField">
|
||||
<label htmlFor="confirmPassword">
|
||||
{' '}
|
||||
Confirm New 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 && (
|
||||
<ButtonSpinner />
|
||||
)}
|
||||
</button>
|
||||
</p>{' '}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ChangePasswordForm.displayName = 'ChangePasswordForm'
|
||||
ChangePasswordForm.displayName = 'ChangePasswordForm';
|
||||
|
||||
function validate(values) {
|
||||
const errors = {};
|
||||
if (!Validate.text(values.password)) {
|
||||
errors.password = 'Password is required.'
|
||||
}
|
||||
if (Validate.text(values.password) && !Validate.isStrongPassword(values.password)) {
|
||||
errors.password = 'Password should be atleast 8 characters long'
|
||||
}
|
||||
if (!Validate.text(values.confirmPassword)) {
|
||||
errors.confirmPassword = 'Confirm Password is required.';
|
||||
}
|
||||
if (!Validate.compare(values.password, values.confirmPassword)) {
|
||||
errors.confirmPassword = 'Password and confirm password should match.';
|
||||
}
|
||||
return errors;
|
||||
const errors = {};
|
||||
if (!Validate.text(values.password)) {
|
||||
errors.password = 'Password is required.';
|
||||
}
|
||||
if (
|
||||
Validate.text(values.password) &&
|
||||
!Validate.isStrongPassword(values.password)
|
||||
) {
|
||||
errors.password = 'Password should be atleast 8 characters long';
|
||||
}
|
||||
if (!Validate.text(values.confirmPassword)) {
|
||||
errors.confirmPassword = 'Confirm Password is required.';
|
||||
}
|
||||
if (!Validate.compare(values.password, values.confirmPassword)) {
|
||||
errors.confirmPassword = 'Password and confirm password should match.';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
const changePasswordForm = reduxForm({
|
||||
form: 'changePasswordForm', // a unique identifier for this form
|
||||
validate
|
||||
form: 'changePasswordForm', // a unique identifier for this form
|
||||
validate,
|
||||
})(ChangePasswordForm);
|
||||
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
changePasswordError, changePasswordSuccess, changePassword, resetChangePassword
|
||||
}, dispatch);
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return bindActionCreators(
|
||||
{
|
||||
changePasswordError,
|
||||
changePasswordSuccess,
|
||||
changePassword,
|
||||
resetChangePassword,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
changePasswordState: state.changePassword
|
||||
};
|
||||
return {
|
||||
changePasswordState: state.changePassword,
|
||||
};
|
||||
}
|
||||
|
||||
ChangePasswordForm.propTypes = {
|
||||
changePassword: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
changePasswordState: PropTypes.object.isRequired,
|
||||
token: PropTypes.any
|
||||
}
|
||||
changePassword: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
changePasswordState: PropTypes.object.isRequired,
|
||||
token: PropTypes.any,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(changePasswordForm);
|
||||
|
||||
@@ -1,182 +1,209 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
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';
|
||||
|
||||
import { RenderField } from '../basic/RenderField';
|
||||
import { Validate } from '../../config';
|
||||
import { FlatLoader } from '../basic/Loader.js';
|
||||
|
||||
const errorStyle = {
|
||||
color:'red'
|
||||
}
|
||||
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>
|
||||
)
|
||||
}
|
||||
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'
|
||||
CompanyForm.displayName = 'CompanyForm';
|
||||
|
||||
const validate = function(values){
|
||||
const error = {};
|
||||
const validate = function(values) {
|
||||
const error = {};
|
||||
|
||||
if(!Validate.text(values.companyName)){
|
||||
error.companyName = 'Company name is required.'
|
||||
}
|
||||
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.companyRole)) {
|
||||
error.companyRole = 'Job Title is required.';
|
||||
}
|
||||
|
||||
if(!Validate.text(values.companyPhoneNumber)){
|
||||
error.companyPhoneNumber ='Phone Number 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.comapnySize)) {
|
||||
error.comapnySize = 'Phone Number is required.';
|
||||
}
|
||||
|
||||
if(!Validate.text(values.reference)){
|
||||
error.reference ='This is required.'
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
if (!Validate.text(values.reference)) {
|
||||
error.reference = 'This is required.';
|
||||
}
|
||||
|
||||
return error;
|
||||
};
|
||||
|
||||
const companyForm = reduxForm({
|
||||
form: 'CompanyForm', // <------ same form name
|
||||
destroyOnUnmount: false, // <------ preserve form data
|
||||
forceUnregisterOnUnmount: true,
|
||||
validate // <------ unregister fields on unmoun
|
||||
form: 'CompanyForm', // <------ same form name
|
||||
destroyOnUnmount: false, // <------ preserve form data
|
||||
forceUnregisterOnUnmount: true,
|
||||
validate, // <------ unregister fields on unmoun
|
||||
})(CompanyForm);
|
||||
|
||||
const mapDispatchToProps = (dispatch_Ignored) => {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
const mapDispatchToProps = dispatch_Ignored => {
|
||||
return {};
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
register: state.register
|
||||
};
|
||||
return {
|
||||
register: state.register,
|
||||
};
|
||||
}
|
||||
|
||||
CompanyForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
submitForm: PropTypes.func.isRequired
|
||||
}
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
submitForm: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(companyForm);
|
||||
|
||||
@@ -1,152 +1,166 @@
|
||||
import React, { Component } from 'react'
|
||||
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 { ButtonSpinner } from '../basic/Loader.js';
|
||||
import { loginError, loginSuccess, loginUser, resetLogin } from '../../actions/login';
|
||||
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';
|
||||
|
||||
const errorStyle = {
|
||||
color: '#c23d4b'
|
||||
}
|
||||
color: '#c23d4b',
|
||||
};
|
||||
export class LoginForm extends Component {
|
||||
state = {
|
||||
serverResponse: '',
|
||||
};
|
||||
|
||||
state = {
|
||||
serverResponse: ''
|
||||
}
|
||||
componentDidMount() {
|
||||
const query = queryString.parse(this.props.location.search).status;
|
||||
let 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;
|
||||
const loginError = this.props.login.error;
|
||||
let header;
|
||||
if (loginError) {
|
||||
header = <span style={errorStyle}>{loginError}</span>;
|
||||
} else if (serverResponse) {
|
||||
header = <span>{serverResponse}</span>;
|
||||
} else {
|
||||
header = <span>Welcome back!</span>;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const query = queryString.parse(this.props.location.search).status;
|
||||
let 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;
|
||||
const loginError = this.props.login.error;
|
||||
let header;
|
||||
if (loginError) {
|
||||
header = <span style={errorStyle}>{loginError}</span>
|
||||
}
|
||||
else if (serverResponse) {
|
||||
header = <span>{serverResponse}</span>
|
||||
} else {
|
||||
header = <span>Welcome back!</span>
|
||||
}
|
||||
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>{header}</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>
|
||||
|
||||
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>
|
||||
{header}
|
||||
</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</span>}
|
||||
{this.props.login.requesting && <ButtonSpinner />}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<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</span>
|
||||
)}
|
||||
{this.props.login.requesting && (
|
||||
<ButtonSpinner />
|
||||
)}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
LoginForm.displayName = 'LoginForm'
|
||||
LoginForm.displayName = 'LoginForm';
|
||||
|
||||
const validate = function (values) {
|
||||
const errors = {};
|
||||
if (!Validate.text(values.email)) {
|
||||
errors.email = 'Email is required.'
|
||||
}
|
||||
const 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.';
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (!Validate.email(values.email)) {
|
||||
errors.email = 'Email is invalid.'
|
||||
}
|
||||
}
|
||||
if (!Validate.text(values.password)) {
|
||||
errors.password = 'Password is required.';
|
||||
}
|
||||
|
||||
if (!Validate.text(values.password)) {
|
||||
errors.password = 'Password is required.'
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
return errors;
|
||||
};
|
||||
|
||||
const loginForm = reduxForm({
|
||||
form: 'LoginForm', // a unique identifier for this form
|
||||
validate,
|
||||
destroyOnUnmount: false
|
||||
form: 'LoginForm', // a unique identifier for this form
|
||||
validate,
|
||||
destroyOnUnmount: false,
|
||||
})(LoginForm);
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
loginError, loginSuccess, loginUser, resetLogin
|
||||
}, dispatch);
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return bindActionCreators(
|
||||
{
|
||||
loginError,
|
||||
loginSuccess,
|
||||
loginUser,
|
||||
resetLogin,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
login: state.login
|
||||
};
|
||||
return {
|
||||
login: state.login,
|
||||
};
|
||||
}
|
||||
|
||||
LoginForm.propTypes = {
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
login: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired
|
||||
}
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
login: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(loginForm);
|
||||
|
||||
@@ -1,101 +1,135 @@
|
||||
import React, { Component } from 'react'
|
||||
import { reduxForm } from 'redux-form'
|
||||
import React, { Component } from 'react';
|
||||
import { reduxForm } from 'redux-form';
|
||||
import UserForm from './UserForm';
|
||||
import CardForm from './CardForm';
|
||||
import { connect } from 'react-redux';
|
||||
import { signupUser, incrementStep, decrementStep, saveUserState, isUserInvited } from '../../actions/register'
|
||||
import { bindActionCreators } from 'redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { setUserId, setUserProperties, identify, logEvent } from '../../analytics';
|
||||
import { IS_DEV } from '../../config';
|
||||
|
||||
export class RegisterForm extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
userFormSubmitted = (values) => {
|
||||
const 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 (!IS_DEV) {
|
||||
setUserId(user.data.id);
|
||||
identify(user.data.id);
|
||||
setUserProperties({
|
||||
'Name': user.data.name,
|
||||
'Created': new Date(),
|
||||
'Email': user.data.email
|
||||
});
|
||||
logEvent('Sign up completed for invited user', { 'First Time': 'TRUE', 'id': user.data.id });
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
thisObj.props.incrementStep();
|
||||
if (!IS_DEV) {
|
||||
setUserId(values.email);
|
||||
identify(values.email);
|
||||
setUserProperties({
|
||||
'Name': values.name,
|
||||
'Created': new Date(),
|
||||
'Email': values.email,
|
||||
'CompanyName': values.companyName,
|
||||
'CompanyPhoneNumber': values.companyPhoneNumber
|
||||
});
|
||||
logEvent('Sign up step one completed', { 'First Time': 'TRUE' });
|
||||
}
|
||||
}
|
||||
}, function (error) {
|
||||
return error
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { step } = this.props.register;
|
||||
return (
|
||||
<div>
|
||||
{ step === 1 && <UserForm submitForm={this.userFormSubmitted} error={this.props.register.error} location={this.props.location} />}
|
||||
{ step === 2 && <CardForm planId={this.props.planId} error={this.props.register.error} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RegisterForm.displayName = 'RegisterForm';
|
||||
|
||||
const registerForm = reduxForm({
|
||||
form: 'RegisterForm'
|
||||
})(RegisterForm);
|
||||
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
import {
|
||||
signupUser,
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
saveUserState,
|
||||
isUserInvited,
|
||||
}, dispatch);
|
||||
} from '../../actions/register';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
setUserId,
|
||||
setUserProperties,
|
||||
identify,
|
||||
logEvent,
|
||||
} from '../../analytics';
|
||||
import { IS_DEV } from '../../config';
|
||||
|
||||
export class RegisterForm extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
userFormSubmitted = values => {
|
||||
const 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 (!IS_DEV) {
|
||||
setUserId(user.data.id);
|
||||
identify(user.data.id);
|
||||
setUserProperties({
|
||||
Name: user.data.name,
|
||||
Created: new Date(),
|
||||
Email: user.data.email,
|
||||
});
|
||||
logEvent(
|
||||
'Sign up completed for invited user',
|
||||
{
|
||||
'First Time': 'TRUE',
|
||||
id: user.data.id,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
thisObj.props.incrementStep();
|
||||
if (!IS_DEV) {
|
||||
setUserId(values.email);
|
||||
identify(values.email);
|
||||
setUserProperties({
|
||||
Name: values.name,
|
||||
Created: new Date(),
|
||||
Email: values.email,
|
||||
CompanyName: values.companyName,
|
||||
CompanyPhoneNumber: values.companyPhoneNumber,
|
||||
});
|
||||
logEvent('Sign up step one completed', {
|
||||
'First Time': 'TRUE',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
function(error) {
|
||||
return error;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { step } = this.props.register;
|
||||
return (
|
||||
<div>
|
||||
{step === 1 && (
|
||||
<UserForm
|
||||
submitForm={this.userFormSubmitted}
|
||||
error={this.props.register.error}
|
||||
location={this.props.location}
|
||||
/>
|
||||
)}
|
||||
{step === 2 && (
|
||||
<CardForm
|
||||
planId={this.props.planId}
|
||||
error={this.props.register.error}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
RegisterForm.displayName = 'RegisterForm';
|
||||
|
||||
const registerForm = reduxForm({
|
||||
form: 'RegisterForm',
|
||||
})(RegisterForm);
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return bindActionCreators(
|
||||
{
|
||||
signupUser,
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
saveUserState,
|
||||
isUserInvited,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
register: state.register
|
||||
};
|
||||
return {
|
||||
register: state.register,
|
||||
};
|
||||
}
|
||||
RegisterForm.propTypes = {
|
||||
saveUserState: PropTypes.func.isRequired,
|
||||
isUserInvited: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
planId: PropTypes.string.isRequired,
|
||||
location: PropTypes.object.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);
|
||||
|
||||
@@ -1,113 +1,156 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { Validate } from '../../config';
|
||||
import { ButtonSpinner } from '../basic/Loader.js';
|
||||
import { resetPasswordError, resetPasswordSuccess, resetPassword, resetResetPassword } from '../../actions/resetPassword';
|
||||
import {
|
||||
resetPasswordError,
|
||||
resetPasswordSuccess,
|
||||
resetPassword,
|
||||
resetResetPassword,
|
||||
} from '../../actions/resetPassword';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { RenderField } from '../basic/RenderField';
|
||||
|
||||
const errorStyle = {
|
||||
color: '#c23d4b'
|
||||
}
|
||||
color: '#c23d4b',
|
||||
};
|
||||
|
||||
export class ResetPasswordForm extends Component {
|
||||
submitForm = values => {
|
||||
this.props.resetPassword(values);
|
||||
};
|
||||
|
||||
submitForm = (values) => {
|
||||
this.props.resetPassword(values);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const resetPasswordError = this.props.resetPasswordState.error;
|
||||
let header;
|
||||
if (resetPasswordError) {
|
||||
header = <span style={errorStyle} id="error-msg">{resetPasswordError}</span>
|
||||
} else {
|
||||
header = <span>Reset Password.</span>
|
||||
}
|
||||
|
||||
|
||||
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" >
|
||||
<div className="title">
|
||||
<h2>
|
||||
{header}
|
||||
</h2>
|
||||
</div>
|
||||
{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"
|
||||
/>
|
||||
render() {
|
||||
const resetPasswordError = this.props.resetPasswordState.error;
|
||||
let header;
|
||||
if (resetPasswordError) {
|
||||
header = (
|
||||
<span style={errorStyle} id="error-msg">
|
||||
{resetPasswordError}
|
||||
</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 && <ButtonSpinner />}
|
||||
</button>
|
||||
</p> </div>}
|
||||
);
|
||||
} else {
|
||||
header = <span>Reset Password.</span>;
|
||||
}
|
||||
|
||||
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">
|
||||
<div className="title">
|
||||
<h2>{header}</h2>
|
||||
</div>
|
||||
{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 && (
|
||||
<ButtonSpinner />
|
||||
)}
|
||||
</button>
|
||||
</p>{' '}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ResetPasswordForm.displayName = 'ResetPasswordForm'
|
||||
ResetPasswordForm.displayName = 'ResetPasswordForm';
|
||||
|
||||
function validate(values) {
|
||||
const errors = {};
|
||||
if (!Validate.text(values.email)) {
|
||||
errors.email = 'Email is required.'
|
||||
}
|
||||
else if (!Validate.email(values.email)) {
|
||||
errors.email = 'Email is invalid.'
|
||||
}
|
||||
return errors;
|
||||
const errors = {};
|
||||
if (!Validate.text(values.email)) {
|
||||
errors.email = 'Email is required.';
|
||||
} else if (!Validate.email(values.email)) {
|
||||
errors.email = 'Email is invalid.';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
const resetPasswordForm = reduxForm({
|
||||
form: 'resetPasswordForm', // a unique identifier for this form
|
||||
validate
|
||||
form: 'resetPasswordForm', // a unique identifier for this form
|
||||
validate,
|
||||
})(ResetPasswordForm);
|
||||
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
resetPasswordError, resetPasswordSuccess, resetPassword, resetResetPassword
|
||||
}, dispatch);
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return bindActionCreators(
|
||||
{
|
||||
resetPasswordError,
|
||||
resetPasswordSuccess,
|
||||
resetPassword,
|
||||
resetResetPassword,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
resetPasswordState: state.resetPassword
|
||||
};
|
||||
return {
|
||||
resetPasswordState: state.resetPassword,
|
||||
};
|
||||
}
|
||||
|
||||
ResetPasswordForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
resetPasswordState: PropTypes.object.isRequired,
|
||||
resetPassword: PropTypes.func.isRequired
|
||||
}
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
resetPasswordState: PropTypes.object.isRequired,
|
||||
resetPassword: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(resetPasswordForm);
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(resetPasswordForm);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
@@ -12,223 +12,351 @@ import { logEvent } from '../../analytics';
|
||||
import { IS_DEV } from '../../config';
|
||||
|
||||
class UserForm extends Component {
|
||||
state = {
|
||||
serverResponse: '',
|
||||
};
|
||||
|
||||
state = {
|
||||
serverResponse: ''
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const query = queryString.parse(this.props.location.search).status;
|
||||
if (query === 'z1hb0g8vfg0rWM1Ly1euQSZ1L5ZNHuAk') {
|
||||
this.setState({
|
||||
serverResponse: 'No user found for this token'
|
||||
});
|
||||
}
|
||||
removeQuery();
|
||||
}
|
||||
componentDidMount() {
|
||||
const query = queryString.parse(this.props.location.search).status;
|
||||
if (query === 'z1hb0g8vfg0rWM1Ly1euQSZ1L5ZNHuAk') {
|
||||
this.setState({
|
||||
serverResponse: 'No user found for this token',
|
||||
});
|
||||
}
|
||||
removeQuery();
|
||||
}
|
||||
|
||||
trackClick = (target) => {
|
||||
const { formValues } = this.props;
|
||||
const allowedValues = ['email', 'name', 'companyName', 'companyPhoneNumber'];
|
||||
const filteredValues = formValues && Object.keys(formValues)
|
||||
.filter(key => allowedValues.includes(key))
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = formValues[key];
|
||||
return obj;
|
||||
}, {});
|
||||
trackClick = target => {
|
||||
const { formValues } = this.props;
|
||||
const allowedValues = [
|
||||
'email',
|
||||
'name',
|
||||
'companyName',
|
||||
'companyPhoneNumber',
|
||||
];
|
||||
const filteredValues =
|
||||
formValues &&
|
||||
Object.keys(formValues)
|
||||
.filter(key => allowedValues.includes(key))
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = formValues[key];
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
if (!IS_DEV) {
|
||||
logEvent(`Register page click on # ${target.id}`, { data: filteredValues});
|
||||
}
|
||||
}
|
||||
if (!IS_DEV) {
|
||||
logEvent(`Register page click on # ${target.id}`, {
|
||||
data: filteredValues,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { serverResponse } = this.state;
|
||||
return (
|
||||
<div id="main-body" className="box css" style={{ width: 500 }} onClick={(event) => this.trackClick(event.target)}>
|
||||
<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)}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<p className="text" style={{ display: 'block', maxWidth: '50%', marginTop: 0 }}>
|
||||
<span id="email">
|
||||
<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" style={{ display: 'block', maxWidth: '50%', marginTop: 0 }}>
|
||||
<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>
|
||||
</div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<p className="text" style={{ display: 'block', maxWidth: '50%', marginTop: 0 }}>
|
||||
<span>
|
||||
<label htmlFor="companyName">Company Name</label>
|
||||
<Field
|
||||
type="text"
|
||||
name="companyName"
|
||||
id="companyName"
|
||||
component={RenderField}
|
||||
placeholder="Company Name"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="text" style={{ display: 'block', maxWidth: '50%', marginTop: 0 }}>
|
||||
<span>
|
||||
<label htmlFor="companyPhoneNumber">Phone Number</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="companyPhoneNumber"
|
||||
id="companyPhoneNumber"
|
||||
placeholder="+1-123-456-7890"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<p className="text" style={{ display: 'block', maxWidth: '50%', marginTop: 0 }}>
|
||||
<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" style={{ display: 'block', maxWidth: '50%', marginTop: 0 }}>
|
||||
<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" style={{ width: '100%', maxWidth: '100%' }}>
|
||||
<button style={{ width: '100%' }} 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 ) ? <ButtonSpinner /> : <span>Sign Up</span>}
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
const { serverResponse } = this.state;
|
||||
return (
|
||||
<div
|
||||
id="main-body"
|
||||
className="box css"
|
||||
style={{ width: 500 }}
|
||||
onClick={event => this.trackClick(event.target)}
|
||||
>
|
||||
<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
|
||||
)}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<p
|
||||
className="text"
|
||||
style={{
|
||||
display: 'block',
|
||||
maxWidth: '50%',
|
||||
marginTop: 0,
|
||||
}}
|
||||
>
|
||||
<span id="email">
|
||||
<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"
|
||||
style={{
|
||||
display: 'block',
|
||||
maxWidth: '50%',
|
||||
marginTop: 0,
|
||||
}}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<p
|
||||
className="text"
|
||||
style={{
|
||||
display: 'block',
|
||||
maxWidth: '50%',
|
||||
marginTop: 0,
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
<label htmlFor="companyName">
|
||||
Company Name
|
||||
</label>
|
||||
<Field
|
||||
type="text"
|
||||
name="companyName"
|
||||
id="companyName"
|
||||
component={RenderField}
|
||||
placeholder="Company Name"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p
|
||||
className="text"
|
||||
style={{
|
||||
display: 'block',
|
||||
maxWidth: '50%',
|
||||
marginTop: 0,
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
<label htmlFor="companyPhoneNumber">
|
||||
Phone Number
|
||||
</label>
|
||||
<Field
|
||||
type="text"
|
||||
component={RenderField}
|
||||
name="companyPhoneNumber"
|
||||
id="companyPhoneNumber"
|
||||
placeholder="+1-123-456-7890"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<p
|
||||
className="text"
|
||||
style={{
|
||||
display: 'block',
|
||||
maxWidth: '50%',
|
||||
marginTop: 0,
|
||||
}}
|
||||
>
|
||||
<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"
|
||||
style={{
|
||||
display: 'block',
|
||||
maxWidth: '50%',
|
||||
marginTop: 0,
|
||||
}}
|
||||
>
|
||||
<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"
|
||||
style={{ width: '100%', maxWidth: '100%' }}
|
||||
>
|
||||
<button
|
||||
style={{ width: '100%' }}
|
||||
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) ? (
|
||||
<ButtonSpinner />
|
||||
) : (
|
||||
<span>Sign Up</span>
|
||||
)}
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UserForm.displayName = 'UserForm'
|
||||
UserForm.displayName = 'UserForm';
|
||||
|
||||
const validate = function (values) {
|
||||
const error = {};
|
||||
const validate = function(values) {
|
||||
const error = {};
|
||||
|
||||
if (!Validate.text(values.name))
|
||||
error.name = 'Name is required.';
|
||||
if (!Validate.text(values.name)) error.name = 'Name is required.';
|
||||
|
||||
if(Validate.text(values.name) && !Validate.isValidName(values.name))
|
||||
error.name = 'Name is not valid.';
|
||||
if (Validate.text(values.name) && !Validate.isValidName(values.name))
|
||||
error.name = 'Name is not valid.';
|
||||
|
||||
if (!Validate.text(values.email))
|
||||
error.email = 'Email 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.email) && !Validate.email(values.email))
|
||||
error.email = 'Email is not valid.';
|
||||
|
||||
if (!Validate.text(values.companyName))
|
||||
error.companyName = 'Company name is required.';
|
||||
if (
|
||||
!Validate.isValidBusinessEmail(values.email) &&
|
||||
Validate.email(values.email)
|
||||
)
|
||||
error.email = 'Please enter a business email address.';
|
||||
|
||||
if (!Validate.text(values.companyPhoneNumber))
|
||||
error.companyPhoneNumber = 'Phone number is required.';
|
||||
if (!Validate.text(values.companyName))
|
||||
error.companyName = 'Company name is required.';
|
||||
|
||||
if (Validate.text(values.companyPhoneNumber) && !Validate.isValidNumber(values.companyPhoneNumber))
|
||||
error.companyPhoneNumber = 'Phone number is invalid.';
|
||||
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.password) && !Validate.isStrongPassword(values.password)) {
|
||||
error.password = 'Password should be atleast 8 characters long'
|
||||
}
|
||||
if (
|
||||
Validate.text(values.companyPhoneNumber) &&
|
||||
!Validate.isValidNumber(values.companyPhoneNumber)
|
||||
)
|
||||
error.companyPhoneNumber = 'Phone number is invalid.';
|
||||
|
||||
if (!Validate.text(values.confirmPassword))
|
||||
error.confirmPassword = 'Confirm Password is required.';
|
||||
if (!Validate.text(values.password))
|
||||
error.password = 'Password is required.';
|
||||
if (
|
||||
Validate.text(values.password) &&
|
||||
!Validate.isStrongPassword(values.password)
|
||||
) {
|
||||
error.password = 'Password should be atleast 8 characters long';
|
||||
}
|
||||
|
||||
if (!Validate.compare(values.password, values.confirmPassword)) {
|
||||
error.confirmPassword = 'Password and confirm password should match.';
|
||||
}
|
||||
if (!Validate.text(values.confirmPassword))
|
||||
error.confirmPassword = 'Confirm Password is required.';
|
||||
|
||||
return error;
|
||||
if (!Validate.compare(values.password, values.confirmPassword)) {
|
||||
error.confirmPassword = 'Password and confirm password should match.';
|
||||
}
|
||||
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
const userForm = reduxForm({
|
||||
form: 'UserSignupForm', // <------ same form name
|
||||
destroyOnUnmount: false,
|
||||
validate
|
||||
form: 'UserSignupForm', // <------ same form name
|
||||
destroyOnUnmount: false,
|
||||
validate,
|
||||
})(UserForm);
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
|
||||
}, dispatch);
|
||||
}
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return bindActionCreators({}, dispatch);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
register: state.register,
|
||||
formValues: state.form && state.form.UserSignupForm && state.form.UserSignupForm.values
|
||||
};
|
||||
return {
|
||||
register: state.register,
|
||||
formValues:
|
||||
state.form &&
|
||||
state.form.UserSignupForm &&
|
||||
state.form.UserSignupForm.values,
|
||||
};
|
||||
}
|
||||
|
||||
UserForm.propTypes = {
|
||||
submitForm: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
formValues: PropTypes.object
|
||||
}
|
||||
submitForm: PropTypes.func.isRequired,
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
register: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
formValues: PropTypes.object,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(userForm);
|
||||
|
||||
@@ -3,5 +3,5 @@ export const companySize = [
|
||||
{ name: '11-50', code: '11-50' },
|
||||
{ name: '51-200', code: '51-200' },
|
||||
{ name: '200-1000', code: '200-1000' },
|
||||
{ name: '1000+', code: '1000+' }
|
||||
];
|
||||
{ name: '1000+', code: '1000+' },
|
||||
];
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { companySize } from './CompanySizeList';
|
||||
|
||||
const errorStyle = {
|
||||
color: 'red',
|
||||
topMargin: '5px'
|
||||
}
|
||||
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>
|
||||
)
|
||||
<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.displayName = 'CompanySizeSelector';
|
||||
|
||||
CompanySizeSelector.propTypes = {
|
||||
meta: PropTypes.object.isRequired,
|
||||
input: PropTypes.object.isRequired,
|
||||
id: PropTypes.string
|
||||
}
|
||||
meta: PropTypes.object.isRequired,
|
||||
input: PropTypes.object.isRequired,
|
||||
id: PropTypes.string,
|
||||
};
|
||||
|
||||
export default CompanySizeSelector
|
||||
export default CompanySizeSelector;
|
||||
|
||||
@@ -52,7 +52,7 @@ export const countries = [
|
||||
{ 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: "Cote d'Ivoire", code: 'CI' },
|
||||
{ name: 'Croatia', code: 'HR' },
|
||||
{ name: 'Cuba', code: 'CU' },
|
||||
{ name: 'Cyprus', code: 'CY' },
|
||||
@@ -114,11 +114,11 @@ export const countries = [
|
||||
{ name: 'Kazakhstan', code: 'KZ' },
|
||||
{ name: 'Kenya', code: 'KE' },
|
||||
{ name: 'Kiribati', code: 'KI' },
|
||||
{ name: 'Korea, Democratic People\'s Republic of', code: 'KP' },
|
||||
{ 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: "Lao People's Democratic Republic", code: 'LA' },
|
||||
{ name: 'Latvia', code: 'LV' },
|
||||
{ name: 'Lebanon', code: 'LB' },
|
||||
{ name: 'Lesotho', code: 'LS' },
|
||||
@@ -241,5 +241,5 @@ export const countries = [
|
||||
{ name: 'Western Sahara', code: 'EH' },
|
||||
{ name: 'Yemen', code: 'YE' },
|
||||
{ name: 'Zambia', code: 'ZM' },
|
||||
{ name: 'Zimbabwe', code: 'ZW' }
|
||||
{ name: 'Zimbabwe', code: 'ZW' },
|
||||
];
|
||||
|
||||
@@ -1,35 +1,42 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { countries } from './CountryList';
|
||||
|
||||
const errorStyle = {
|
||||
color: '#c23d4b',
|
||||
topMargin:'5px'
|
||||
}
|
||||
color: '#c23d4b',
|
||||
topMargin: '5px',
|
||||
};
|
||||
|
||||
const selectorStyle = {
|
||||
color: '#000000'
|
||||
}
|
||||
color: '#000000',
|
||||
};
|
||||
|
||||
const CountrySelector = ({ input, meta: { touched, error } }) => (
|
||||
const CountrySelector = ({ input, meta: { touched, error } }) => (
|
||||
<span>
|
||||
<select {...input} className="selector" id="country" style={{ width: 222 }}>
|
||||
<option style = {selectorStyle} value="">Select Country...</option>
|
||||
{countries.map(val => (
|
||||
<option style = {selectorStyle} value={val.name} key={val.code}>
|
||||
{val.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{touched && error && <span style={errorStyle}>{error}</span>}
|
||||
<select
|
||||
{...input}
|
||||
className="selector"
|
||||
id="country"
|
||||
style={{ width: 222 }}
|
||||
>
|
||||
<option style={selectorStyle} value="">
|
||||
Select Country...
|
||||
</option>
|
||||
{countries.map(val => (
|
||||
<option style={selectorStyle} value={val.name} key={val.code}>
|
||||
{val.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{touched && error && <span style={errorStyle}>{error}</span>}
|
||||
</span>
|
||||
)
|
||||
);
|
||||
|
||||
CountrySelector.displayName = 'CountrySelector'
|
||||
CountrySelector.displayName = 'CountrySelector';
|
||||
|
||||
CountrySelector.propTypes = {
|
||||
CountrySelector.propTypes = {
|
||||
meta: PropTypes.object.isRequired,
|
||||
input: PropTypes.object.isRequired
|
||||
}
|
||||
input: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default CountrySelector
|
||||
export default CountrySelector;
|
||||
|
||||
@@ -4,41 +4,57 @@ import { logEvent } from '../../analytics';
|
||||
import { IS_DEV } from '../../config';
|
||||
|
||||
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 (!IS_DEV) {
|
||||
logEvent('Error', { error, info });
|
||||
}
|
||||
} catch (error) {
|
||||
return error
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { hasError: false };
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div id="app-loading" style={{ 'position': 'fixed', 'top': '0', 'bottom': '0', 'left': '0', 'right': '0', 'backgroundColor': '#fdfdfd', 'zIndex': '999', 'display': 'flex', 'justifyContent': 'center', 'alignItems': 'center' }}>
|
||||
<div>An unexpected error has occured. Please reload the page to continue</div>
|
||||
</div>
|
||||
)
|
||||
componentDidCatch(error, info) {
|
||||
// Display fallback UI
|
||||
this.setState({ hasError: true });
|
||||
// You can also log the error to an error reporting service
|
||||
try {
|
||||
if (!IS_DEV) {
|
||||
logEvent('Error', { 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: '#fdfdfd',
|
||||
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;
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
ErrorBoundary.displayName = 'ErrorBoundary';
|
||||
|
||||
ErrorBoundary.propTypes = {
|
||||
children: PropTypes.any
|
||||
}
|
||||
children: PropTypes.any,
|
||||
};
|
||||
|
||||
export default ErrorBoundary;
|
||||
export default ErrorBoundary;
|
||||
|
||||
@@ -1,25 +1,63 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const loaderStyle = {
|
||||
backgroundColor: '#96d8ff'
|
||||
}
|
||||
backgroundColor: '#96d8ff',
|
||||
};
|
||||
|
||||
export const FlatLoader = () => (<div className="ball-pulse"><div style={loaderStyle}></div><div style={loaderStyle}></div><div style={loaderStyle}></div></div>);
|
||||
export const FlatLoader = () => (
|
||||
<div className="ball-pulse">
|
||||
<div style={loaderStyle}></div>
|
||||
<div style={loaderStyle}></div>
|
||||
<div style={loaderStyle}></div>
|
||||
</div>
|
||||
);
|
||||
|
||||
FlatLoader.displayName = 'FlatLoader'
|
||||
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>);
|
||||
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'
|
||||
FormLoader.displayName = 'FormLoader';
|
||||
|
||||
export const ListLoader = () => (<div className="ball-beat" style={{ textAlign: 'center', marginTop: '20px' }}><div style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}></div><div style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}></div><div style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}></div></div>);
|
||||
export const ListLoader = () => (
|
||||
<div
|
||||
className="ball-beat"
|
||||
style={{ textAlign: 'center', marginTop: '20px' }}
|
||||
>
|
||||
<div
|
||||
style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}
|
||||
></div>
|
||||
<div
|
||||
style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}
|
||||
></div>
|
||||
<div
|
||||
style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
|
||||
ListLoader.displayName = 'ListLoader'
|
||||
ListLoader.displayName = 'ListLoader';
|
||||
|
||||
export const TeamListLoader = () => (<div className="ball-beat" style={{ textAlign: 'center',width:'95px'}}><div style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}></div><div style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}></div><div style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}></div></div>);
|
||||
export const TeamListLoader = () => (
|
||||
<div className="ball-beat" style={{ textAlign: 'center', width: '95px' }}>
|
||||
<div
|
||||
style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}
|
||||
></div>
|
||||
<div
|
||||
style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}
|
||||
></div>
|
||||
<div
|
||||
style={{ height: '8px', width: '8px', backgroundColor: '#4c4c4c' }}
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
|
||||
TeamListLoader.displayName = 'TeamListLoader'
|
||||
TeamListLoader.displayName = 'TeamListLoader';
|
||||
|
||||
export const Spinner = () => (
|
||||
<div className="Spinner bs-SpinnerLegacy Spinner--color--white Box-root Flex-inlineFlex Flex-alignItems--center Flex-justifyContent--center">
|
||||
@@ -37,17 +75,20 @@ export const Spinner = () => (
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
Spinner.displayName = 'Spinner'
|
||||
Spinner.displayName = 'Spinner';
|
||||
|
||||
export const ButtonSpinner = () => (
|
||||
<div className="Spinner bs-SpinnerLegacy Spinner--color--white Box-root Flex-inlineFlex Flex-alignItems--center Flex-justifyContent--center" style={{ marginTop: 4 }}>
|
||||
<div
|
||||
className="Spinner bs-SpinnerLegacy Spinner--color--white Box-root Flex-inlineFlex Flex-alignItems--center Flex-justifyContent--center"
|
||||
style={{ marginTop: 4 }}
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="Spinner-svg"
|
||||
style={{ width: 25, height: 25 }}
|
||||
className="Spinner-svg"
|
||||
style={{ width: 25, height: 25 }}
|
||||
>
|
||||
<ellipse
|
||||
cx={12}
|
||||
@@ -58,49 +99,49 @@ export const ButtonSpinner = () => (
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
|
||||
ButtonSpinner.displayName = 'ButtonSpinner'
|
||||
|
||||
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'
|
||||
ButtonSpinner.displayName = 'ButtonSpinner';
|
||||
|
||||
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';
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const errorStyle = {
|
||||
color:'#c23d4b',
|
||||
width: '222px'
|
||||
}
|
||||
|
||||
const RenderField = ({ input, placeholder, type, meta, className, id, disabled, initialValue, style }) => (
|
||||
color: '#c23d4b',
|
||||
width: '222px',
|
||||
};
|
||||
|
||||
const RenderField = ({
|
||||
input,
|
||||
placeholder,
|
||||
type,
|
||||
meta,
|
||||
className,
|
||||
id,
|
||||
disabled,
|
||||
initialValue,
|
||||
style,
|
||||
}) => (
|
||||
<span>
|
||||
<span>
|
||||
<input
|
||||
@@ -21,21 +30,16 @@ const RenderField = ({ input, placeholder, type, meta, className, id, disabled,
|
||||
style={style || {}}
|
||||
/>
|
||||
</span>
|
||||
{meta.error &&
|
||||
meta.touched &&
|
||||
<span style={errorStyle}>
|
||||
{meta.error}
|
||||
</span>}
|
||||
{meta.error && meta.touched && (
|
||||
<span style={errorStyle}>{meta.error}</span>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
);
|
||||
|
||||
RenderField.displayName = 'RenderField'
|
||||
RenderField.displayName = 'RenderField';
|
||||
|
||||
RenderField.propTypes = {
|
||||
initialValue: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.bool,
|
||||
]),
|
||||
initialValue: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
||||
input: PropTypes.object.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
type: PropTypes.string.isRequired,
|
||||
@@ -44,10 +48,7 @@ RenderField.propTypes = {
|
||||
meta: PropTypes.object.isRequired,
|
||||
rows: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
style: PropTypes.object
|
||||
}
|
||||
|
||||
export {RenderField}
|
||||
|
||||
|
||||
style: PropTypes.object,
|
||||
};
|
||||
|
||||
export { RenderField };
|
||||
|
||||
@@ -14,7 +14,10 @@ let developmentEnv = false;
|
||||
|
||||
export function env(value) {
|
||||
const { _env } = window;
|
||||
return (_env && _env[`REACT_APP_${value}`]) || process.env[`REACT_APP_${value}`];
|
||||
return (
|
||||
(_env && _env[`REACT_APP_${value}`]) ||
|
||||
process.env[`REACT_APP_${value}`]
|
||||
);
|
||||
}
|
||||
|
||||
if (!isServer) {
|
||||
@@ -24,18 +27,19 @@ if (!isServer) {
|
||||
domain = 'localhost';
|
||||
adminDashboardUrl = 'http://localhost:3100';
|
||||
developmentEnv = true;
|
||||
}
|
||||
else if (env('BACKEND_HOST')) {
|
||||
} else if (env('BACKEND_HOST')) {
|
||||
apiUrl = env('BACKEND_HOST');
|
||||
dashboardUrl = env('DASHBOARD_HOST');
|
||||
domain = env('DOMAIN');
|
||||
if (apiUrl.indexOf('staging') > -1 || apiUrl.indexOf('app.local') > -1) {
|
||||
if (
|
||||
apiUrl.indexOf('staging') > -1 ||
|
||||
apiUrl.indexOf('app.local') > -1
|
||||
) {
|
||||
developmentEnv = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const API_URL = apiUrl;
|
||||
|
||||
export const DASHBOARD_URL = dashboardUrl;
|
||||
@@ -47,7 +51,6 @@ export const ADMIN_DASHBOARD_URL = adminDashboardUrl;
|
||||
export const IS_DEV = developmentEnv;
|
||||
|
||||
export const User = {
|
||||
|
||||
getAccessToken() {
|
||||
return localStorage.getItem('access_token');
|
||||
},
|
||||
@@ -112,15 +115,13 @@ export const User = {
|
||||
|
||||
isLoggedIn() {
|
||||
return localStorage.getItem('access_token') ? true : false;
|
||||
}
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
//Data validation Util goes in here.
|
||||
export const Validate = {
|
||||
|
||||
isDomain(domain) {
|
||||
return (domain.search(/\./) >= 0);
|
||||
return domain.search(/\./) >= 0;
|
||||
},
|
||||
|
||||
url(url) {
|
||||
@@ -128,7 +129,6 @@ export const Validate = {
|
||||
},
|
||||
|
||||
text(text) {
|
||||
|
||||
if (!text || text.trim() === '') {
|
||||
return false;
|
||||
}
|
||||
@@ -137,37 +137,34 @@ export const Validate = {
|
||||
},
|
||||
|
||||
number(number) {
|
||||
|
||||
if (number && number.length && !isNaN(number)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
isValidNumber(number) {
|
||||
// eslint-disable-next-line
|
||||
if(number.match('^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$')) {
|
||||
if (number.match('^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-s./0-9]*$')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
isStrongPassword(password) {
|
||||
if(password.match('^(?=.{8,})')) {
|
||||
if (password.match('^(?=.{8,})')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
email(email) {
|
||||
if (this.text(email))
|
||||
return isEmail(email);
|
||||
if (this.text(email)) return isEmail(email);
|
||||
return false;
|
||||
},
|
||||
|
||||
isValidBusinessEmail(email){
|
||||
isValidBusinessEmail(email) {
|
||||
return emaildomains.test(email);
|
||||
},
|
||||
|
||||
@@ -215,36 +212,38 @@ export const Validate = {
|
||||
return true;
|
||||
},
|
||||
|
||||
isValidName(name) {
|
||||
isValidName(name) {
|
||||
// eslint-disable-next-line
|
||||
if(name.match('[A-Z][a-zA-Z][^#&<>\"~;$^%{}?]{1,20}$')) {
|
||||
return true
|
||||
if (name.match('[A-Z][a-zA-Z][^#&<>"~;$^%{}?]{1,20}$')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const PricingPlan = {
|
||||
|
||||
getPlans() {
|
||||
|
||||
if (window.location.href.indexOf('localhost') > -1 || window.location.href.indexOf('staging') > -1 || window.location.href.indexOf('app.local') > -1) {
|
||||
if (
|
||||
window.location.href.indexOf('localhost') > -1 ||
|
||||
window.location.href.indexOf('staging') > -1 ||
|
||||
window.location.href.indexOf('app.local') > -1
|
||||
) {
|
||||
return [
|
||||
{
|
||||
category: 'Basic',
|
||||
planId: 'plan_EgTJMZULfh6THW',
|
||||
type: 'month',
|
||||
amount: 8,
|
||||
details: '$8 / Month / User'
|
||||
details: '$8 / Month / User',
|
||||
},
|
||||
{
|
||||
category: 'Basic',
|
||||
planId: 'plan_EgTQAx3Z909Dne',
|
||||
type: 'annual',
|
||||
amount: 80.4,
|
||||
details: '$80.4 / Year / User'
|
||||
details: '$80.4 / Year / User',
|
||||
},
|
||||
/* {
|
||||
/* {
|
||||
category: 'Pro',
|
||||
planId: 'plan_CpIZEEfT4YFSvF',
|
||||
type: 'month',
|
||||
@@ -272,7 +271,7 @@ export const PricingPlan = {
|
||||
amount: 1180,
|
||||
details: '$1180 / Year'
|
||||
} */
|
||||
]
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
@@ -280,16 +279,16 @@ export const PricingPlan = {
|
||||
planId: 'plan_EgT8cUrwsxaqCs',
|
||||
type: 'month',
|
||||
amount: 8,
|
||||
details: '$8 / Month / User'
|
||||
details: '$8 / Month / User',
|
||||
},
|
||||
{
|
||||
category: 'Basic',
|
||||
planId: 'plan_EgT9hrq9GdIGQ6',
|
||||
type: 'annual',
|
||||
amount: 80.4,
|
||||
details: '$80.4 / Year / User'
|
||||
details: '$80.4 / Year / User',
|
||||
},
|
||||
/* {
|
||||
/* {
|
||||
category: 'Pro',
|
||||
planId: 'plan_CogeidQkPwkycV',
|
||||
type: 'month',
|
||||
@@ -317,7 +316,7 @@ export const PricingPlan = {
|
||||
amount: 1180,
|
||||
details: '$1180 / Year'
|
||||
}*/
|
||||
]
|
||||
];
|
||||
}
|
||||
},
|
||||
|
||||
@@ -326,57 +325,79 @@ export const PricingPlan = {
|
||||
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>,
|
||||
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>,
|
||||
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>,
|
||||
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>,
|
||||
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>,
|
||||
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;
|
||||
@@ -388,7 +409,7 @@ export function getQueryVar(variable, url) {
|
||||
return decodeURIComponent(results[2].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
export function saveFile(content, filename){
|
||||
const blob = new Blob([content], {type: 'text/plain;charset=utf-8'});
|
||||
export function saveFile(content, filename) {
|
||||
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
|
||||
FileSaver.saveAs(blob, filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
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';
|
||||
export const RESET_CHANGEPASSWORD = 'auth/RESET_CHANGEPASSWORD';
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -11,7 +11,11 @@ export const AUTH_VERIFICATION_REQUEST = 'auth/AUTH_VERIFICATION_REQUEST';
|
||||
export const RESET_AUTH_VERIFICATION = 'auth/RESET_AUTH_VERIFICATION';
|
||||
|
||||
// Use backup code for logging in a user
|
||||
export const BACKUP_CODE_VERIFICATION_SUCCESS = 'auth/BACKUP_CODE_VERIFICATION_SUCCESS';
|
||||
export const BACKUP_CODE_VERIFICATION_FAILED = 'auth/BACKUP_CODE_VERIFICATION_FAILED';
|
||||
export const BACKUP_CODE_VERIFICATION_REQUEST = 'auth/BACKUP_CODE_VERIFICATION_REQUEST';
|
||||
export const RESET_BACKUP_CODE_VERIFICATION = 'auth/RESET_BACKUP_CODE_VERIFICATION';
|
||||
export const BACKUP_CODE_VERIFICATION_SUCCESS =
|
||||
'auth/BACKUP_CODE_VERIFICATION_SUCCESS';
|
||||
export const BACKUP_CODE_VERIFICATION_FAILED =
|
||||
'auth/BACKUP_CODE_VERIFICATION_FAILED';
|
||||
export const BACKUP_CODE_VERIFICATION_REQUEST =
|
||||
'auth/BACKUP_CODE_VERIFICATION_REQUEST';
|
||||
export const RESET_BACKUP_CODE_VERIFICATION =
|
||||
'auth/RESET_BACKUP_CODE_VERIFICATION';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export const OPEN_MODAL = 'OPEN_MODAL';
|
||||
export const CLOSE_MODAL = 'CLOSE_MODAL';
|
||||
export const CLOSE_MODAL = 'CLOSE_MODAL';
|
||||
|
||||
@@ -12,7 +12,7 @@ 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 IS_USER_INVITED_FETCH = 'register/IS_USER_INVITED_FETCH';
|
||||
|
||||
export const SKIP_CARD_STEP = 'register/SKIP_CARD_STEP';
|
||||
|
||||
@@ -20,4 +20,4 @@ export const ADD_CARD_SUCCESS = 'ADD_CARD_SUCCESS';
|
||||
export const ADD_CARD_FAILED = 'ADD_CARD_FAILED';
|
||||
export const ADD_CARD_REQUEST = 'ADD_CARD_REQUEST';
|
||||
|
||||
export const SAVE_PLAN_ID= 'SAVE_PLAN_ID';
|
||||
export const SAVE_PLAN_ID = 'SAVE_PLAN_ID';
|
||||
|
||||
@@ -1,4 +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';
|
||||
export const RESET_PASSWORDRESET = 'auth/RESET_PASSWORDRESET';
|
||||
|
||||
@@ -1,46 +1,50 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
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>;
|
||||
}
|
||||
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: PropTypes.array.isRequired,
|
||||
closeModal: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
Modals.displayName = 'BlackBoneModals'
|
||||
Modals.displayName = 'BlackBoneModals';
|
||||
|
||||
export default connect(
|
||||
function mapStateToProps(state) {
|
||||
return state.modal
|
||||
},
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators({
|
||||
closeModal
|
||||
}, dispatch);
|
||||
}
|
||||
)(Modals);
|
||||
function mapStateToProps(state) {
|
||||
return state.modal;
|
||||
},
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(
|
||||
{
|
||||
closeModal,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
}
|
||||
)(Modals);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
export default (error)=>{
|
||||
switch (error.toString()){
|
||||
export default error => {
|
||||
switch (error.toString()) {
|
||||
case 'Error: Network Error':
|
||||
return 'Check your network connection.'
|
||||
return 'Check your network connection.';
|
||||
default:
|
||||
return error
|
||||
return error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
body {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
background-color: #f7f7f7
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
@@ -10,18 +10,19 @@ import './index.css';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
|
||||
if (!isServer) {
|
||||
ReactGA.initialize('UA-115085157-1');
|
||||
ReactGA.initialize('UA-115085157-1');
|
||||
}
|
||||
const target = document.getElementById('root');
|
||||
|
||||
render (
|
||||
<Provider store={store} history={history}>
|
||||
<Frontload noServerRender={true}>
|
||||
<ErrorBoundary>
|
||||
<App />
|
||||
</ErrorBoundary>
|
||||
</Frontload>
|
||||
</Provider>,target
|
||||
render(
|
||||
<Provider store={store} history={history}>
|
||||
<Frontload noServerRender={true}>
|
||||
<ErrorBoundary>
|
||||
<App />
|
||||
</ErrorBoundary>
|
||||
</Frontload>
|
||||
</Provider>,
|
||||
target
|
||||
);
|
||||
|
||||
// this will enable the app to work offline and load faster
|
||||
|
||||
@@ -1,82 +1,82 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
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;
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
//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';
|
||||
}
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
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;
|
||||
return null;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch_Ignored => {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
ChangePasswordPage.propTypes = {
|
||||
match: PropTypes.object.isRequired
|
||||
}
|
||||
match: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
ChangePasswordPage.displayName = 'ChangePasswordPage'
|
||||
ChangePasswordPage.displayName = 'ChangePasswordPage';
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ChangePasswordPage);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
@@ -11,112 +11,118 @@ import { IS_DEV } from '../config';
|
||||
import { history } from '../store';
|
||||
|
||||
class LoginPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
submitHandler = values => {
|
||||
this.props.loginUser(values).then(user => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if (!IS_DEV) {
|
||||
identify(user.data.id);
|
||||
setUserId(user.data.id);
|
||||
logEvent('Log in user', { id: user.data.id });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
submitHandler = (values) => {
|
||||
this.props.loginUser(values).then((user) => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if(!IS_DEV){
|
||||
identify(user.data.id);
|
||||
setUserId(user.data.id);
|
||||
logEvent('Log in user', { id: user.data.id })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
render() {
|
||||
const { login } = this.props;
|
||||
|
||||
render() {
|
||||
const { login } = this.props;
|
||||
if (login.success && !login.user.tokens) {
|
||||
history.push('/user-auth/token');
|
||||
}
|
||||
|
||||
if (login.success && !login.user.tokens) {
|
||||
history.push('/user-auth/token');
|
||||
}
|
||||
return (
|
||||
<div id="wrap">
|
||||
<div id="header">
|
||||
<h1>
|
||||
<a aria-hidden={false} href="/">
|
||||
Fyipe
|
||||
</a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
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 &&
|
||||
this.props.login.error === 'Verify your email first.' ? (
|
||||
<div>
|
||||
<MessageBox
|
||||
title="Your email is not verified."
|
||||
//eslint-disable-next-line
|
||||
message={`An email is on its way to you with new verification link. Please don't forget to check spam.`}
|
||||
>
|
||||
<div className="below-box">
|
||||
<p>
|
||||
Click{' '}
|
||||
<Link to="/user-verify/resend">here</Link>{' '}
|
||||
to resend verification link to your email.
|
||||
</p>
|
||||
</div>
|
||||
</MessageBox>
|
||||
</div>
|
||||
) : (
|
||||
<LoginForm onSubmit={this.submitHandler} {...this.props} />
|
||||
)}
|
||||
|
||||
{/* LOGIN BOX */}
|
||||
{!this.props.login.success
|
||||
&& this.props.login.error
|
||||
&& this.props.login.error === 'Verify your email first.' ?
|
||||
<div>
|
||||
<MessageBox
|
||||
title='Your email is not verified.'
|
||||
//eslint-disable-next-line
|
||||
message={`An email is on its way to you with new verification link. Please don't forget to check spam.`} >
|
||||
<div className="below-box">
|
||||
<p>
|
||||
Click <Link to="/user-verify/resend">here</Link> to resend verification link to your email.
|
||||
</p>
|
||||
</div>
|
||||
</MessageBox>
|
||||
</div> :
|
||||
<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>
|
||||
|
||||
{/* 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>
|
||||
);
|
||||
}
|
||||
{/* 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
|
||||
};
|
||||
return {
|
||||
login: state.login,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => bindActionCreators(
|
||||
{ loginUser, loginError }, dispatch);
|
||||
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,
|
||||
]),
|
||||
location: PropTypes.object,
|
||||
}
|
||||
loginUser: PropTypes.func.isRequired,
|
||||
login: PropTypes.object,
|
||||
success: PropTypes.bool,
|
||||
error: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
|
||||
location: PropTypes.object,
|
||||
};
|
||||
|
||||
LoginPage.displayName = 'LoginPage'
|
||||
LoginPage.displayName = 'LoginPage';
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LoginPage);
|
||||
|
||||
@@ -1,95 +1,107 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import RegisterForm from '../components/auth/RegisterForm';
|
||||
import queryString from 'query-string';
|
||||
import {PricingPlan} from '../config';
|
||||
import { PricingPlan } from '../config';
|
||||
import MessageBox from '../components/MessageBox';
|
||||
import { savePlanId } from '../actions/register';
|
||||
|
||||
class RegisterPage extends React.Component {
|
||||
componentWillUnmount() {
|
||||
document.body.id = '';
|
||||
document.body.className = '';
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.body.id = '';
|
||||
document.body.className = '';
|
||||
}
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.className = 'register-page';
|
||||
document.body.style.overflow = 'auto';
|
||||
this.planId =
|
||||
queryString.parse(this.props.location.search).planId || null;
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.className = 'register-page';
|
||||
document.body.style.overflow = 'auto';
|
||||
this.planId = queryString.parse(this.props.location.search).planId || null;
|
||||
if (!this.planId) {
|
||||
this.planId = PricingPlan.getPlans()[0].planId;
|
||||
}
|
||||
this.props.savePlanId(this.planId);
|
||||
}
|
||||
|
||||
if(!this.planId){
|
||||
this.planId = PricingPlan.getPlans()[0].planId;
|
||||
}
|
||||
this.props.savePlanId(this.planId);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div id="wrap" style={{ paddingTop: 0 }}>
|
||||
{/* Header */}
|
||||
<div id="header">
|
||||
<h1>
|
||||
<a href="/">Fyipe</a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
render() {
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
{/* 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
|
||||
};
|
||||
return {
|
||||
register: state.register,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
savePlanId
|
||||
}, dispatch);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return bindActionCreators(
|
||||
{
|
||||
savePlanId,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
};
|
||||
|
||||
RegisterPage.propTypes = {
|
||||
location: PropTypes.object.isRequired,
|
||||
register:PropTypes.object,
|
||||
success:PropTypes.bool,
|
||||
savePlanId: PropTypes.func.isRequired
|
||||
}
|
||||
location: PropTypes.object.isRequired,
|
||||
register: PropTypes.object,
|
||||
success: PropTypes.bool,
|
||||
savePlanId: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
RegisterPage.displayName = 'RegisterPage';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { Validate } from '../config';
|
||||
@@ -12,152 +12,198 @@ import queryString from 'query-string';
|
||||
import { removeQuery } from '../store';
|
||||
|
||||
const errorStyle = {
|
||||
color: '#c23d4b'
|
||||
}
|
||||
color: '#c23d4b',
|
||||
};
|
||||
export class ResendTokenForm extends Component {
|
||||
state = {
|
||||
serverResponse: ''
|
||||
}
|
||||
|
||||
submitForm = (values) => {
|
||||
this.props.resendToken(values);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
const 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;
|
||||
const resendTokenError = this.props.resendTokenState.error;
|
||||
let header;
|
||||
if(success) {
|
||||
header = <span>Verification Email Sent</span>
|
||||
} else if (resendTokenError) {
|
||||
header = <span style={errorStyle} id="error-msg">{resendTokenError}</span>
|
||||
} else if (serverResponse) {
|
||||
header = <span style={errorStyle} id="error-msg">{serverResponse}</span>
|
||||
} else {
|
||||
header = <span>Resend verification email.</span>
|
||||
}
|
||||
state = {
|
||||
serverResponse: '',
|
||||
};
|
||||
|
||||
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" >
|
||||
<div className="title">
|
||||
<h2>
|
||||
{header}
|
||||
</h2>
|
||||
submitForm = values => {
|
||||
this.props.resendToken(values);
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
const 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;
|
||||
const resendTokenError = this.props.resendTokenState.error;
|
||||
let header;
|
||||
if (success) {
|
||||
header = <span>Verification Email Sent</span>;
|
||||
} else if (resendTokenError) {
|
||||
header = (
|
||||
<span style={errorStyle} id="error-msg">
|
||||
{resendTokenError}
|
||||
</span>
|
||||
);
|
||||
} else if (serverResponse) {
|
||||
header = (
|
||||
<span style={errorStyle} id="error-msg">
|
||||
{serverResponse}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
header = <span>Resend verification email.</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="wrap" style={{ paddingTop: 0 }}>
|
||||
<div id="header">
|
||||
<h1>
|
||||
<a href="/">Fyipe</a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{this.props.resendTokenState.success && <p id="resend-verification-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>}
|
||||
<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">
|
||||
<div className="title">
|
||||
<h2>{header}</h2>
|
||||
</div>
|
||||
|
||||
{this.props.resendTokenState.success && (
|
||||
<p
|
||||
id="resend-verification-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 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>
|
||||
)
|
||||
}
|
||||
{!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 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'
|
||||
ResendTokenForm.displayName = 'ResendTokenForm';
|
||||
|
||||
function validate(values) {
|
||||
const errors = {};
|
||||
if (!Validate.text(values.email)) {
|
||||
errors.email = 'Email is required.'
|
||||
}
|
||||
else if (!Validate.email(values.email)) {
|
||||
errors.email = 'Email is invalid.'
|
||||
}
|
||||
return errors;
|
||||
const errors = {};
|
||||
if (!Validate.text(values.email)) {
|
||||
errors.email = 'Email is required.';
|
||||
} else if (!Validate.email(values.email)) {
|
||||
errors.email = 'Email is invalid.';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
const resendTokenForm = reduxForm({
|
||||
form: 'resendTokenForm',
|
||||
validate
|
||||
form: 'resendTokenForm',
|
||||
validate,
|
||||
})(ResendTokenForm);
|
||||
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return bindActionCreators({
|
||||
resendToken
|
||||
}, dispatch);
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return bindActionCreators(
|
||||
{
|
||||
resendToken,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
resendTokenState: state.resendToken
|
||||
};
|
||||
return {
|
||||
resendTokenState: state.resendToken,
|
||||
};
|
||||
}
|
||||
|
||||
ResendTokenForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
resendTokenState: PropTypes.object.isRequired,
|
||||
resendToken: PropTypes.func.isRequired,
|
||||
location: PropTypes.object.isRequired
|
||||
}
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
resendTokenState: PropTypes.object.isRequired,
|
||||
resendToken: PropTypes.func.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(resendTokenForm);
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(resendTokenForm);
|
||||
|
||||
@@ -4,54 +4,54 @@ 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';
|
||||
}
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
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'
|
||||
ResetPasswordPage.displayName = 'ResetPasswordPage';
|
||||
|
||||
export default connect(null, null)(ResetPasswordPage);
|
||||
export default connect(null, null)(ResetPasswordPage);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { ButtonSpinner } from '../components/basic/Loader';
|
||||
@@ -10,124 +10,161 @@ import { Link } from 'react-router-dom';
|
||||
import { identify, setUserId, logEvent } from '../analytics';
|
||||
import { IS_DEV } from '../config';
|
||||
|
||||
const errorStyle = {color: '#c23d4b'};
|
||||
const errorStyle = { color: '#c23d4b' };
|
||||
|
||||
export class VerifyAuthToken extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
submitForm = (values) => {
|
||||
this.props.verifyAuthToken(values).then((user) => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if (!IS_DEV) {
|
||||
identify(user.data.id);
|
||||
setUserId(user.data.id);
|
||||
logEvent('Log in user', { id: user.data.id })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { error } = this.props.login.authToken;
|
||||
let header;
|
||||
|
||||
if (error) {
|
||||
header = <span style={errorStyle}>{error}</span>;
|
||||
} else {
|
||||
header = <span>Two Factor Auth token.</span>;
|
||||
}
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
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" >
|
||||
<div className="title"><h2>{header}</h2></div>
|
||||
submitForm = values => {
|
||||
this.props.verifyAuthToken(values).then(user => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if (!IS_DEV) {
|
||||
identify(user.data.id);
|
||||
setUserId(user.data.id);
|
||||
logEvent('Log in user', { id: user.data.id });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
<p className="error-message hidden" />
|
||||
<p className="message">Enter your auth token below to login.</p>
|
||||
<div>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="token">Verification Token</label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="text"
|
||||
name="token"
|
||||
id="token"
|
||||
placeholder="Token"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" disabled={this.props.login.authToken.requesting}>
|
||||
{!this.props.login.authToken.requesting && <span>Verify token</span>}
|
||||
{this.props.login.authToken.requesting && <ButtonSpinner />}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div className="below-box">
|
||||
<p>
|
||||
Don't have your app authenticator? <Link to="/user-auth/backup">Use Backup code</Link>.
|
||||
</p>
|
||||
</div>
|
||||
<div id="footer_spacer"/>
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
<li><Link to="/login">Sign In</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>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
const { error } = this.props.login.authToken;
|
||||
let header;
|
||||
|
||||
if (error) {
|
||||
header = <span style={errorStyle}>{error}</span>;
|
||||
} else {
|
||||
header = <span>Two Factor Auth token.</span>;
|
||||
}
|
||||
|
||||
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">
|
||||
<div className="title">
|
||||
<h2>{header}</h2>
|
||||
</div>
|
||||
|
||||
<p className="error-message hidden" />
|
||||
<p className="message">
|
||||
Enter your auth token below to login.
|
||||
</p>
|
||||
<div>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="token">
|
||||
Verification Token
|
||||
</label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="text"
|
||||
name="token"
|
||||
id="token"
|
||||
placeholder="Token"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="submit">
|
||||
<button
|
||||
type="submit"
|
||||
className="button blue medium"
|
||||
disabled={
|
||||
this.props.login.authToken
|
||||
.requesting
|
||||
}
|
||||
>
|
||||
{!this.props.login.authToken
|
||||
.requesting && (
|
||||
<span>Verify token</span>
|
||||
)}
|
||||
{this.props.login.authToken
|
||||
.requesting && (
|
||||
<ButtonSpinner />
|
||||
)}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div className="below-box">
|
||||
<p>
|
||||
Don't have your app authenticator?{' '}
|
||||
<Link to="/user-auth/backup">Use Backup code</Link>.
|
||||
</p>
|
||||
</div>
|
||||
<div id="footer_spacer" />
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
<li>
|
||||
<Link to="/login">Sign In</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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyAuthToken.displayName = 'VerifyAuthToken';
|
||||
|
||||
function validate(values) {
|
||||
const errors = {};
|
||||
if (!values.token) {
|
||||
errors.token = 'Please provide token.';
|
||||
}
|
||||
return errors;
|
||||
const errors = {};
|
||||
if (!values.token) {
|
||||
errors.token = 'Please provide token.';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
const verifyAuthTokenForm = reduxForm({
|
||||
form: 'verifyAuthToken',
|
||||
validate
|
||||
form: 'verifyAuthToken',
|
||||
validate,
|
||||
})(VerifyAuthToken);
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {login: state.login};
|
||||
return { login: state.login };
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => bindActionCreators(
|
||||
{ verifyAuthToken }, dispatch
|
||||
);
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ verifyAuthToken }, dispatch);
|
||||
|
||||
VerifyAuthToken.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
verifyAuthToken: PropTypes.func.isRequired,
|
||||
login: PropTypes.object,
|
||||
}
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
verifyAuthToken: PropTypes.func.isRequired,
|
||||
login: PropTypes.object,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(verifyAuthTokenForm);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(verifyAuthTokenForm);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { ButtonSpinner } from '../components/basic/Loader';
|
||||
@@ -10,119 +10,150 @@ import { Link } from 'react-router-dom';
|
||||
import { identify, setUserId, logEvent } from '../analytics';
|
||||
import { IS_DEV } from '../config';
|
||||
|
||||
const errorStyle = {color: '#c23d4b'};
|
||||
const errorStyle = { color: '#c23d4b' };
|
||||
|
||||
export class VerifyBackupCode extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
submitForm = (values) => {
|
||||
this.props.verifyBackupCode(values).then((user) => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if (!IS_DEV) {
|
||||
identify(user.data.id);
|
||||
setUserId(user.data.id);
|
||||
logEvent('Log in user', { id: user.data.id })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { backupCode } = this.props.login;
|
||||
let header;
|
||||
|
||||
if (backupCode.error) {
|
||||
header = <span style={errorStyle}>{backupCode.error}</span>;
|
||||
} else {
|
||||
header = <span>Backup Code.</span>;
|
||||
}
|
||||
componentDidMount() {
|
||||
document.body.id = 'login';
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
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" >
|
||||
<div className="title"><h2>{header}</h2></div>
|
||||
submitForm = values => {
|
||||
this.props.verifyBackupCode(values).then(user => {
|
||||
if (user && user.data && user.data.id) {
|
||||
if (!IS_DEV) {
|
||||
identify(user.data.id);
|
||||
setUserId(user.data.id);
|
||||
logEvent('Log in user', { id: user.data.id });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
<p className="error-message hidden" />
|
||||
<p className="message">Enter your backup code below to login.</p>
|
||||
<div>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="code">Backup Code</label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="text"
|
||||
name="code"
|
||||
id="code"
|
||||
placeholder="Backup Code"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="submit">
|
||||
<button type="submit" className="button blue medium" disabled={backupCode.requesting}>
|
||||
{!backupCode.requesting && <span>Verify Code</span>}
|
||||
{backupCode.requesting && <ButtonSpinner />}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer_spacer"/>
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
<li><Link to="/login">Sign In</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>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
const { backupCode } = this.props.login;
|
||||
let header;
|
||||
|
||||
if (backupCode.error) {
|
||||
header = <span style={errorStyle}>{backupCode.error}</span>;
|
||||
} else {
|
||||
header = <span>Backup Code.</span>;
|
||||
}
|
||||
|
||||
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">
|
||||
<div className="title">
|
||||
<h2>{header}</h2>
|
||||
</div>
|
||||
|
||||
<p className="error-message hidden" />
|
||||
<p className="message">
|
||||
Enter your backup code below to login.
|
||||
</p>
|
||||
<div>
|
||||
<p className="text">
|
||||
<span>
|
||||
<label htmlFor="code">
|
||||
Backup Code
|
||||
</label>
|
||||
<Field
|
||||
component={RenderField}
|
||||
type="text"
|
||||
name="code"
|
||||
id="code"
|
||||
placeholder="Backup Code"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
<p className="submit">
|
||||
<button
|
||||
type="submit"
|
||||
className="button blue medium"
|
||||
disabled={backupCode.requesting}
|
||||
>
|
||||
{!backupCode.requesting && (
|
||||
<span>Verify Code</span>
|
||||
)}
|
||||
{backupCode.requesting && (
|
||||
<ButtonSpinner />
|
||||
)}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer_spacer" />
|
||||
<div id="bottom">
|
||||
<ul>
|
||||
<li>
|
||||
<Link to="/login">Sign In</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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
VerifyBackupCode.displayName = 'VerifyBackupCode';
|
||||
|
||||
function validate(values) {
|
||||
const errors = {};
|
||||
if (!values.code) {
|
||||
errors.code = 'Please provide a backup code.';
|
||||
}
|
||||
return errors;
|
||||
const errors = {};
|
||||
if (!values.code) {
|
||||
errors.code = 'Please provide a backup code.';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
const verifyBackupCodeForm = reduxForm({
|
||||
form: 'verifyBackupCode',
|
||||
validate
|
||||
form: 'verifyBackupCode',
|
||||
validate,
|
||||
})(VerifyBackupCode);
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {login: state.login};
|
||||
return { login: state.login };
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => bindActionCreators(
|
||||
{ verifyBackupCode }, dispatch
|
||||
);
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ verifyBackupCode }, dispatch);
|
||||
|
||||
VerifyBackupCode.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
verifyBackupCode: PropTypes.func,
|
||||
login: PropTypes.object,
|
||||
}
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
verifyBackupCode: PropTypes.func,
|
||||
login: PropTypes.object,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(verifyBackupCodeForm);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(verifyBackupCodeForm);
|
||||
|
||||
@@ -6,7 +6,6 @@ import ResendToken from './ResendToken';
|
||||
import VerifyAuthToken from './VerifyAuthToken';
|
||||
import VerifyBackupCode from './VerifyBackupCode';
|
||||
|
||||
|
||||
export default {
|
||||
ResetPassword,
|
||||
Register,
|
||||
@@ -15,4 +14,4 @@ export default {
|
||||
ResendToken,
|
||||
VerifyAuthToken,
|
||||
VerifyBackupCode,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,44 +1,41 @@
|
||||
import * as types from '../constants/changePassword'
|
||||
import * as types from '../constants/changePassword';
|
||||
|
||||
// The auth reducer. The starting state sets authentication
|
||||
// based on a token being in local storage. In a real app,
|
||||
// we would also want a util to check if the token is expired.
|
||||
|
||||
const initialState = {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false,
|
||||
};
|
||||
|
||||
|
||||
export default function register(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
switch (action.type) {
|
||||
case types.CHANGEPASSWORD_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
requesting: true,
|
||||
error: null,
|
||||
});
|
||||
|
||||
case types.CHANGEPASSWORD_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
requesting: true,
|
||||
error: null
|
||||
});
|
||||
case types.CHANGEPASSWORD_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
});
|
||||
|
||||
case types.CHANGEPASSWORD_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
});
|
||||
case types.CHANGEPASSWORD_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: false,
|
||||
error: action.payload,
|
||||
});
|
||||
|
||||
case types.CHANGEPASSWORD_FAILED:
|
||||
case types.RESET_CHANGEPASSWORD:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: false,
|
||||
error: action.payload,
|
||||
});
|
||||
|
||||
case types.RESET_CHANGEPASSWORD:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@ const appReducer = combineReducers({
|
||||
modal,
|
||||
resetPassword,
|
||||
changePassword,
|
||||
resendToken
|
||||
resendToken,
|
||||
});
|
||||
|
||||
export default (state, action) => {
|
||||
if(action.type === 'CLEAR_STORE'){
|
||||
if (action.type === 'CLEAR_STORE') {
|
||||
state = undefined;
|
||||
}
|
||||
return appReducer(state, action);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,147 +1,143 @@
|
||||
import {
|
||||
LOGIN_REQUEST,
|
||||
LOGIN_SUCCESS,
|
||||
LOGIN_FAILED,
|
||||
RESET_LOGIN,
|
||||
SAVE_STATUS_PAGE,
|
||||
AUTH_VERIFICATION_FAILED,
|
||||
AUTH_VERIFICATION_REQUEST,
|
||||
AUTH_VERIFICATION_SUCCESS,
|
||||
RESET_AUTH_VERIFICATION,
|
||||
BACKUP_CODE_VERIFICATION_FAILED,
|
||||
BACKUP_CODE_VERIFICATION_REQUEST,
|
||||
BACKUP_CODE_VERIFICATION_SUCCESS,
|
||||
RESET_BACKUP_CODE_VERIFICATION
|
||||
LOGIN_REQUEST,
|
||||
LOGIN_SUCCESS,
|
||||
LOGIN_FAILED,
|
||||
RESET_LOGIN,
|
||||
SAVE_STATUS_PAGE,
|
||||
AUTH_VERIFICATION_FAILED,
|
||||
AUTH_VERIFICATION_REQUEST,
|
||||
AUTH_VERIFICATION_SUCCESS,
|
||||
RESET_AUTH_VERIFICATION,
|
||||
BACKUP_CODE_VERIFICATION_FAILED,
|
||||
BACKUP_CODE_VERIFICATION_REQUEST,
|
||||
BACKUP_CODE_VERIFICATION_SUCCESS,
|
||||
RESET_BACKUP_CODE_VERIFICATION,
|
||||
} from '../constants/login';
|
||||
|
||||
|
||||
// The auth reducer. The starting state sets authentication
|
||||
// based on a token being in local storage. In a real app,
|
||||
// we would also want a util to check if the token is expired.
|
||||
|
||||
const initialState = {
|
||||
requesting: false,
|
||||
user: {},
|
||||
error: null,
|
||||
success: false,
|
||||
statusPageLogin: false,
|
||||
statusPageURL: null,
|
||||
authToken: {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
backupCode: {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false,
|
||||
}
|
||||
requesting: false,
|
||||
user: {},
|
||||
error: null,
|
||||
success: false,
|
||||
statusPageLogin: false,
|
||||
statusPageURL: null,
|
||||
authToken: {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
backupCode: {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
export default function register(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
switch (action.type) {
|
||||
case LOGIN_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
requesting: true,
|
||||
error: null,
|
||||
});
|
||||
case LOGIN_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
user: action.payload,
|
||||
});
|
||||
case LOGIN_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: false,
|
||||
error: action.payload,
|
||||
});
|
||||
|
||||
case LOGIN_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
requesting: true,
|
||||
error: null
|
||||
});
|
||||
case LOGIN_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
user: action.payload,
|
||||
});
|
||||
case LOGIN_FAILED:
|
||||
case RESET_LOGIN:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success:false,
|
||||
error: action.payload,
|
||||
});
|
||||
case AUTH_VERIFICATION_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
authToken: {
|
||||
...initialState.authToken,
|
||||
requesting: true,
|
||||
error: null,
|
||||
success: true,
|
||||
},
|
||||
});
|
||||
case AUTH_VERIFICATION_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
authToken: {
|
||||
...initialState.authToken,
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: true,
|
||||
},
|
||||
});
|
||||
case AUTH_VERIFICATION_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
authToken: {
|
||||
...initialState.authToken,
|
||||
requesting: false,
|
||||
error: action.payload,
|
||||
success: false,
|
||||
},
|
||||
});
|
||||
|
||||
case RESET_LOGIN:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
case AUTH_VERIFICATION_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
authToken: {
|
||||
...initialState.authToken,
|
||||
requesting: true,
|
||||
error: null,
|
||||
success: true,
|
||||
}
|
||||
});
|
||||
case AUTH_VERIFICATION_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
authToken: {
|
||||
...initialState.authToken,
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: true,
|
||||
}
|
||||
});
|
||||
case AUTH_VERIFICATION_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
authToken: {
|
||||
...initialState.authToken,
|
||||
requesting: false,
|
||||
error: action.payload,
|
||||
success: false,
|
||||
}
|
||||
});
|
||||
case RESET_AUTH_VERIFICATION:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
case RESET_AUTH_VERIFICATION:
|
||||
return Object.assign({}, state, initialState);
|
||||
// Use back up code to login a user
|
||||
|
||||
// Use back up code to login a user
|
||||
|
||||
case BACKUP_CODE_VERIFICATION_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
backupCode: {
|
||||
...initialState.backupCode,
|
||||
requesting: true,
|
||||
error: null,
|
||||
success: true,
|
||||
}
|
||||
});
|
||||
case BACKUP_CODE_VERIFICATION_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
backupCode: {
|
||||
...initialState.backupCode,
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: true,
|
||||
}
|
||||
});
|
||||
case BACKUP_CODE_VERIFICATION_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
backupCode: {
|
||||
...initialState.backupCode,
|
||||
requesting: false,
|
||||
error: action.payload,
|
||||
success: false,
|
||||
}
|
||||
});
|
||||
case BACKUP_CODE_VERIFICATION_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
backupCode: {
|
||||
...initialState.backupCode,
|
||||
requesting: true,
|
||||
error: null,
|
||||
success: true,
|
||||
},
|
||||
});
|
||||
case BACKUP_CODE_VERIFICATION_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
backupCode: {
|
||||
...initialState.backupCode,
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: true,
|
||||
},
|
||||
});
|
||||
case BACKUP_CODE_VERIFICATION_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
...initialState,
|
||||
backupCode: {
|
||||
...initialState.backupCode,
|
||||
requesting: false,
|
||||
error: action.payload,
|
||||
success: false,
|
||||
},
|
||||
});
|
||||
|
||||
case RESET_BACKUP_CODE_VERIFICATION:
|
||||
return Object.assign({}, state, initialState);
|
||||
case RESET_BACKUP_CODE_VERIFICATION:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
case SAVE_STATUS_PAGE:
|
||||
return Object.assign({}, state, {
|
||||
statusPageLogin: action.payload.statusPageLogin,
|
||||
statusPageURL: action.payload.statusPageURL
|
||||
})
|
||||
case SAVE_STATUS_PAGE:
|
||||
return Object.assign({}, state, {
|
||||
statusPageLogin: action.payload.statusPageLogin,
|
||||
statusPageURL: action.payload.statusPageURL,
|
||||
});
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
|
||||
import { OPEN_MODAL, CLOSE_MODAL} from '../constants/modal'
|
||||
import { OPEN_MODAL, CLOSE_MODAL } from '../constants/modal';
|
||||
|
||||
const initialState = {
|
||||
modals: [],
|
||||
feedbackModalVisble:false
|
||||
feedbackModalVisble: false,
|
||||
};
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case OPEN_MODAL:
|
||||
return Object.assign({}, state, {
|
||||
modals: state.modals.concat(action.payload)
|
||||
modals: state.modals.concat(action.payload),
|
||||
});
|
||||
|
||||
case CLOSE_MODAL:
|
||||
return Object.assign({}, state, {
|
||||
modals: state.modals.filter(item => item.id !== action.payload.id)
|
||||
modals: state.modals.filter(
|
||||
item => item.id !== action.payload.id
|
||||
),
|
||||
});
|
||||
|
||||
default: return state;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,164 +1,159 @@
|
||||
import {
|
||||
SIGNUP_SUCCESS,
|
||||
SIGNUP_FAILED,
|
||||
SIGNUP_STEP_INC,
|
||||
SIGNUP_STEP_DEC,
|
||||
SIGNUP_REQUEST,
|
||||
RESET_SIGNUP,
|
||||
SAVE_CARD_STATE,
|
||||
SAVE_USER_STATE,
|
||||
SAVE_COMPANY_STATE,
|
||||
IS_USER_INVITED_FAILED,
|
||||
IS_USER_INVITED_REQUEST,
|
||||
IS_USER_INVITED_RESET,
|
||||
IS_USER_INVITED_SUCCESS,
|
||||
SKIP_CARD_STEP,
|
||||
ADD_CARD_REQUEST,
|
||||
ADD_CARD_SUCCESS,
|
||||
ADD_CARD_FAILED,
|
||||
SAVE_PLAN_ID
|
||||
} from '../constants/register.js'
|
||||
|
||||
SIGNUP_SUCCESS,
|
||||
SIGNUP_FAILED,
|
||||
SIGNUP_STEP_INC,
|
||||
SIGNUP_STEP_DEC,
|
||||
SIGNUP_REQUEST,
|
||||
RESET_SIGNUP,
|
||||
SAVE_CARD_STATE,
|
||||
SAVE_USER_STATE,
|
||||
SAVE_COMPANY_STATE,
|
||||
IS_USER_INVITED_FAILED,
|
||||
IS_USER_INVITED_REQUEST,
|
||||
IS_USER_INVITED_RESET,
|
||||
IS_USER_INVITED_SUCCESS,
|
||||
SKIP_CARD_STEP,
|
||||
ADD_CARD_REQUEST,
|
||||
ADD_CARD_SUCCESS,
|
||||
ADD_CARD_FAILED,
|
||||
SAVE_PLAN_ID,
|
||||
} from '../constants/register.js';
|
||||
|
||||
// The register state reducer.
|
||||
const initialState = {
|
||||
addCard: {
|
||||
addCard: {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false,
|
||||
card: {}
|
||||
card: {},
|
||||
},
|
||||
requesting: false,
|
||||
step: 1,
|
||||
user: {},
|
||||
card: {},
|
||||
company: {},
|
||||
error: null,
|
||||
success: false,
|
||||
planId: null,
|
||||
isUserInvited: {
|
||||
requesting: false,
|
||||
isUserInvited: null,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
requesting: false,
|
||||
step: 1,
|
||||
user: {},
|
||||
card: {},
|
||||
company: {},
|
||||
error: null,
|
||||
success: false,
|
||||
planId: null,
|
||||
isUserInvited: {
|
||||
requesting: false,
|
||||
isUserInvited: null,
|
||||
error: null,
|
||||
success: false
|
||||
}
|
||||
};
|
||||
|
||||
export default function register(state = initialState, action) {
|
||||
let incCount,decCount,stage;
|
||||
switch (action.type) {
|
||||
case SIGNUP_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
requesting: true,
|
||||
error: null
|
||||
});
|
||||
case SIGNUP_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
});
|
||||
case SIGNUP_FAILED:
|
||||
let incCount, decCount, stage;
|
||||
switch (action.type) {
|
||||
case SIGNUP_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
requesting: true,
|
||||
error: null,
|
||||
});
|
||||
case SIGNUP_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
});
|
||||
case SIGNUP_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
isAuthenticated: false,
|
||||
error: action.payload,
|
||||
isUserInvited: {
|
||||
...state.isUserInvited,
|
||||
requesting: false,
|
||||
},
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
isAuthenticated: false,
|
||||
error: action.payload,
|
||||
isUserInvited : {
|
||||
...state.isUserInvited,
|
||||
requesting: false,
|
||||
}
|
||||
});
|
||||
case SIGNUP_STEP_INC:
|
||||
incCount = state.step + 1;
|
||||
|
||||
case SIGNUP_STEP_INC:
|
||||
incCount = state.step + 1;
|
||||
return Object.assign({}, state, {
|
||||
step: incCount,
|
||||
error: null,
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
step: incCount,
|
||||
error: null
|
||||
});
|
||||
case SKIP_CARD_STEP:
|
||||
stage = 3;
|
||||
|
||||
case SKIP_CARD_STEP:
|
||||
stage = 3;
|
||||
return Object.assign({}, state, {
|
||||
step: stage,
|
||||
error: null,
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
step: stage,
|
||||
error: null
|
||||
});
|
||||
case SIGNUP_STEP_DEC:
|
||||
decCount = state.step - 1;
|
||||
|
||||
case SIGNUP_STEP_DEC:
|
||||
decCount = state.step - 1;
|
||||
return Object.assign({}, state, {
|
||||
step: decCount,
|
||||
error: null,
|
||||
});
|
||||
case SAVE_USER_STATE:
|
||||
return Object.assign({}, state, {
|
||||
user: action.payload,
|
||||
});
|
||||
case SAVE_CARD_STATE:
|
||||
return Object.assign({}, state, {
|
||||
card: action.payload,
|
||||
});
|
||||
case SAVE_COMPANY_STATE:
|
||||
return Object.assign({}, state, {
|
||||
company: action.payload,
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
step: decCount,
|
||||
error: null
|
||||
});
|
||||
case SAVE_USER_STATE:
|
||||
case RESET_SIGNUP:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
return Object.assign({}, state, {
|
||||
user: action.payload
|
||||
});
|
||||
case SAVE_CARD_STATE:
|
||||
case IS_USER_INVITED_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
isUserInvited: {
|
||||
requesting: false,
|
||||
isUserInvited: null,
|
||||
error: action.payload,
|
||||
success: false,
|
||||
},
|
||||
});
|
||||
case IS_USER_INVITED_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
isUserInvited: {
|
||||
requesting: true,
|
||||
isUserInvited: null,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
card: action.payload
|
||||
});
|
||||
case SAVE_COMPANY_STATE:
|
||||
case IS_USER_INVITED_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
...state,
|
||||
isUserInvited: {
|
||||
requesting: false,
|
||||
isUserInvited: action.payload,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
company: action.payload
|
||||
});
|
||||
|
||||
case RESET_SIGNUP:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
case IS_USER_INVITED_FAILED:
|
||||
|
||||
return Object.assign({}, state, {
|
||||
isUserInvited: {
|
||||
requesting: false,
|
||||
isUserInvited: null,
|
||||
error: action.payload,
|
||||
success: false
|
||||
}
|
||||
});
|
||||
case IS_USER_INVITED_REQUEST:
|
||||
|
||||
return Object.assign({}, state, {
|
||||
isUserInvited: {
|
||||
requesting: true,
|
||||
isUserInvited: null,
|
||||
error: null,
|
||||
success: false
|
||||
}
|
||||
});
|
||||
|
||||
case IS_USER_INVITED_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
...state, isUserInvited: {
|
||||
requesting: false,
|
||||
isUserInvited: action.payload,
|
||||
error: null,
|
||||
success: false
|
||||
}
|
||||
});
|
||||
|
||||
case IS_USER_INVITED_RESET:
|
||||
return Object.assign({}, state, {
|
||||
...state, isUserInvited: {
|
||||
requesting: false,
|
||||
isUserInvited: null,
|
||||
error: null,
|
||||
success: false
|
||||
}
|
||||
});
|
||||
case ADD_CARD_REQUEST:
|
||||
case IS_USER_INVITED_RESET:
|
||||
return Object.assign({}, state, {
|
||||
...state,
|
||||
isUserInvited: {
|
||||
requesting: false,
|
||||
isUserInvited: null,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
});
|
||||
case ADD_CARD_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
...state,
|
||||
addCard: {
|
||||
...state.addCard,
|
||||
requesting: true
|
||||
}
|
||||
requesting: true,
|
||||
},
|
||||
});
|
||||
|
||||
case ADD_CARD_SUCCESS:
|
||||
@@ -168,8 +163,8 @@ export default function register(state = initialState, action) {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: true,
|
||||
card: action.payload
|
||||
}
|
||||
card: action.payload,
|
||||
},
|
||||
});
|
||||
|
||||
case ADD_CARD_FAILED:
|
||||
@@ -178,16 +173,15 @@ export default function register(state = initialState, action) {
|
||||
addCard: {
|
||||
requesting: false,
|
||||
success: false,
|
||||
error: action.payload
|
||||
}
|
||||
});
|
||||
case SAVE_PLAN_ID:
|
||||
error: action.payload,
|
||||
},
|
||||
});
|
||||
case SAVE_PLAN_ID:
|
||||
return Object.assign({}, state, {
|
||||
planId: action.payload,
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
planId: action.payload
|
||||
});
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
import {RESENDTOKEN_FAILED, RESENDTOKEN_REQUEST, RESENDTOKEN_SUCCESS} from '../constants/resendToken';
|
||||
import {
|
||||
RESENDTOKEN_FAILED,
|
||||
RESENDTOKEN_REQUEST,
|
||||
RESENDTOKEN_SUCCESS,
|
||||
} from '../constants/resendToken';
|
||||
|
||||
const initialState = {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false,
|
||||
};
|
||||
|
||||
|
||||
export default function register(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
|
||||
case RESENDTOKEN_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
...state,
|
||||
requesting: true
|
||||
});
|
||||
case RESENDTOKEN_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
});
|
||||
case RESENDTOKEN_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: false,
|
||||
error: action.payload,
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
switch (action.type) {
|
||||
case RESENDTOKEN_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
...state,
|
||||
requesting: true,
|
||||
});
|
||||
case RESENDTOKEN_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
});
|
||||
case RESENDTOKEN_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: false,
|
||||
error: action.payload,
|
||||
});
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,44 @@
|
||||
import {PASSWORDRESET_REQUEST,PASSWORDRESET_SUCCESS, PASSWORDRESET_FAILED, RESET_PASSWORDRESET } from '../constants/resetPassword';
|
||||
|
||||
import {
|
||||
PASSWORDRESET_REQUEST,
|
||||
PASSWORDRESET_SUCCESS,
|
||||
PASSWORDRESET_FAILED,
|
||||
RESET_PASSWORDRESET,
|
||||
} from '../constants/resetPassword';
|
||||
|
||||
// The auth reducer. The starting state sets authentication
|
||||
// based on a token being in local storage. In a real app,
|
||||
// we would also want a util to check if the token is expired.
|
||||
|
||||
const initialState = {
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false
|
||||
requesting: false,
|
||||
error: null,
|
||||
success: false,
|
||||
};
|
||||
|
||||
|
||||
export default function register(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
switch (action.type) {
|
||||
case PASSWORDRESET_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
requesting: true,
|
||||
error: null,
|
||||
});
|
||||
case PASSWORDRESET_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
});
|
||||
case PASSWORDRESET_FAILED:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: false,
|
||||
error: action.payload,
|
||||
});
|
||||
|
||||
case PASSWORDRESET_REQUEST:
|
||||
return Object.assign({}, state, {
|
||||
requesting: true,
|
||||
error: null
|
||||
});
|
||||
case PASSWORDRESET_SUCCESS:
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: true,
|
||||
error: null,
|
||||
});
|
||||
case PASSWORDRESET_FAILED:
|
||||
case RESET_PASSWORDRESET:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
return Object.assign({}, state, {
|
||||
requesting: false,
|
||||
success: false,
|
||||
error: action.payload,
|
||||
});
|
||||
|
||||
case RESET_PASSWORDRESET:
|
||||
return Object.assign({}, state, initialState);
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,109 +1,109 @@
|
||||
import pages from './pages';
|
||||
|
||||
const {
|
||||
Register,
|
||||
Login,
|
||||
ResetPassword,
|
||||
ChangePassword,
|
||||
ResendToken,
|
||||
VerifyAuthToken,
|
||||
VerifyBackupCode
|
||||
Register,
|
||||
Login,
|
||||
ResetPassword,
|
||||
ChangePassword,
|
||||
ResendToken,
|
||||
VerifyAuthToken,
|
||||
VerifyBackupCode,
|
||||
} = pages;
|
||||
|
||||
export const groups = [
|
||||
{
|
||||
group: 'public',
|
||||
isPublic: true,
|
||||
routes: [
|
||||
{
|
||||
title: 'Login',
|
||||
path: '/login',
|
||||
icon: 'home',
|
||||
component: Login,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 1
|
||||
},
|
||||
{
|
||||
title: 'Register',
|
||||
path: '/register',
|
||||
icon: 'home',
|
||||
component: Register,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 2
|
||||
},
|
||||
{
|
||||
title: 'Password Reset',
|
||||
path: '/forgot-password',
|
||||
icon: 'home',
|
||||
component: ResetPassword,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 3
|
||||
},
|
||||
{
|
||||
title: 'Change Password',
|
||||
path: '/change-password/:token',
|
||||
icon: 'home',
|
||||
component: ChangePassword,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 4
|
||||
},
|
||||
{
|
||||
title: 'Resend Verification',
|
||||
path: '/user-verify/resend',
|
||||
icon: 'home',
|
||||
component: ResendToken,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 5
|
||||
},
|
||||
{
|
||||
title: 'Verify Authenticator Token',
|
||||
path: '/user-auth/token',
|
||||
icon: 'home',
|
||||
component: VerifyAuthToken,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 5
|
||||
},
|
||||
{
|
||||
title: 'Verify Backup Code',
|
||||
path: '/user-auth/backup',
|
||||
icon: 'home',
|
||||
component: VerifyBackupCode,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 5
|
||||
},
|
||||
]
|
||||
}
|
||||
{
|
||||
group: 'public',
|
||||
isPublic: true,
|
||||
routes: [
|
||||
{
|
||||
title: 'Login',
|
||||
path: '/login',
|
||||
icon: 'home',
|
||||
component: Login,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 1,
|
||||
},
|
||||
{
|
||||
title: 'Register',
|
||||
path: '/register',
|
||||
icon: 'home',
|
||||
component: Register,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 2,
|
||||
},
|
||||
{
|
||||
title: 'Password Reset',
|
||||
path: '/forgot-password',
|
||||
icon: 'home',
|
||||
component: ResetPassword,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 3,
|
||||
},
|
||||
{
|
||||
title: 'Change Password',
|
||||
path: '/change-password/:token',
|
||||
icon: 'home',
|
||||
component: ChangePassword,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 4,
|
||||
},
|
||||
{
|
||||
title: 'Resend Verification',
|
||||
path: '/user-verify/resend',
|
||||
icon: 'home',
|
||||
component: ResendToken,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 5,
|
||||
},
|
||||
{
|
||||
title: 'Verify Authenticator Token',
|
||||
path: '/user-auth/token',
|
||||
icon: 'home',
|
||||
component: VerifyAuthToken,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 5,
|
||||
},
|
||||
{
|
||||
title: 'Verify Backup Code',
|
||||
path: '/user-auth/backup',
|
||||
icon: 'home',
|
||||
component: VerifyBackupCode,
|
||||
subRoutes: [],
|
||||
isPublic: true,
|
||||
visible: true,
|
||||
index: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const joinFn = (acc = [], curr) => {
|
||||
return acc.concat(curr);
|
||||
return acc.concat(curr);
|
||||
};
|
||||
|
||||
export const allRoutes = groups
|
||||
.map(function merge(group) {
|
||||
const { routes } = group;
|
||||
const subRoutes = routes.map(route => route.subRoutes).reduce(joinFn);
|
||||
return routes.concat(subRoutes);
|
||||
})
|
||||
.reduce(joinFn);
|
||||
.map(function merge(group) {
|
||||
const { routes } = group;
|
||||
const subRoutes = routes.map(route => route.subRoutes).reduce(joinFn);
|
||||
return routes.concat(subRoutes);
|
||||
})
|
||||
.reduce(joinFn);
|
||||
|
||||
export const getGroups = () => groups;
|
||||
|
||||
export default {
|
||||
groups,
|
||||
allRoutes
|
||||
groups,
|
||||
allRoutes,
|
||||
};
|
||||
|
||||
@@ -12,137 +12,136 @@
|
||||
// opt-in, read https://bit.ly/CRA-PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export function register(config) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
if ('serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-workr.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-workr.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('fetch', event => {
|
||||
event.respondWith(
|
||||
caches.match(event.request)
|
||||
.then(function(response) {
|
||||
// Cache hit - return response
|
||||
if (response) {
|
||||
return response;
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl, config);
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://bit.ly/CRA-PWA'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
return fetch(event.request);
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('fetch', event => {
|
||||
event.respondWith(
|
||||
caches.match(event.request).then(function(response) {
|
||||
// Cache hit - return response
|
||||
if (response) {
|
||||
return response;
|
||||
}
|
||||
return fetch(event.request);
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl, config) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl, {scope: '.'})
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
return;
|
||||
}
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the updated precached content has been fetched,
|
||||
// but the previous service worker will still serve the older
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||
);
|
||||
navigator.serviceWorker
|
||||
.register(swUrl, { scope: '.' })
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
if (installingWorker == null) {
|
||||
return;
|
||||
}
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the updated precached content has been fetched,
|
||||
// but the previous service worker will still serve the older
|
||||
// content until all client tabs are closed.
|
||||
console.log(
|
||||
'New content is available and will be used when all ' +
|
||||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
|
||||
);
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
// Execute callback
|
||||
if (config && config.onUpdate) {
|
||||
config.onUpdate(registration);
|
||||
}
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration: ', error);
|
||||
});
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration: ', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl, config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (
|
||||
response.status === 404 ||
|
||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (
|
||||
response.status === 404 ||
|
||||
(contentType != null &&
|
||||
contentType.indexOf('javascript') === -1)
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,18 +8,20 @@ import rootReducer from './reducers';
|
||||
|
||||
// A nice helper to tell us if we're on the server
|
||||
export const isServer = !(
|
||||
typeof window !== 'undefined' &&
|
||||
window.document &&
|
||||
window.document.createElement
|
||||
typeof window !== 'undefined' &&
|
||||
window.document &&
|
||||
window.document.createElement
|
||||
);
|
||||
// export const history = createHistory();
|
||||
const url = '/'
|
||||
export const history = isServer ? createMemoryHistory({ initialEntries: [url]}) : createBrowserHistory();
|
||||
const url = '/';
|
||||
export const history = isServer
|
||||
? createMemoryHistory({ initialEntries: [url] })
|
||||
: createBrowserHistory();
|
||||
|
||||
export const removeQuery = () => {
|
||||
const location = Object.assign({}, history.location);
|
||||
delete location.search;
|
||||
history.push(location);
|
||||
const location = Object.assign({}, history.location);
|
||||
delete location.search;
|
||||
history.push(location);
|
||||
};
|
||||
const initialState = {};
|
||||
const enhancers = [];
|
||||
@@ -27,16 +29,15 @@ const logger = createLogger();
|
||||
const middleware = [thunk, routerMiddleware(history)];
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
let devToolsExtension;
|
||||
if (!isServer) {
|
||||
devToolsExtension = window.devToolsExtension;
|
||||
}
|
||||
middleware.push(logger);
|
||||
|
||||
let devToolsExtension
|
||||
if (!isServer) {
|
||||
devToolsExtension = window.devToolsExtension;
|
||||
}
|
||||
middleware.push(logger);
|
||||
|
||||
if (typeof devToolsExtension === 'function') {
|
||||
enhancers.push(devToolsExtension());
|
||||
}
|
||||
if (typeof devToolsExtension === 'function') {
|
||||
enhancers.push(devToolsExtension());
|
||||
}
|
||||
}
|
||||
|
||||
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers);
|
||||
|
||||
@@ -3,17 +3,17 @@ const workboxBuild = require('workbox-build');
|
||||
|
||||
// NOTE: This should be run *AFTER* all your assets are built
|
||||
const buildSW = () => {
|
||||
// This will return a Promise
|
||||
return workboxBuild.injectManifest({
|
||||
swSrc: 'src/sw-template.js', // this is your sw template file
|
||||
swDest: 'build/service-workr.js', // this will be created in the build step
|
||||
globDirectory: 'build',
|
||||
globPatterns: [
|
||||
'**\/*.{js,css,html,png}',
|
||||
]
|
||||
}).then(({count, size}) => {
|
||||
// Optionally, log any warnings and details.
|
||||
return `${count} files will be precached, totaling ${size} bytes.`;
|
||||
});
|
||||
}
|
||||
// This will return a Promise
|
||||
return workboxBuild
|
||||
.injectManifest({
|
||||
swSrc: 'src/sw-template.js', // this is your sw template file
|
||||
swDest: 'build/service-workr.js', // this will be created in the build step
|
||||
globDirectory: 'build',
|
||||
globPatterns: ['**/*.{js,css,html,png}'],
|
||||
})
|
||||
.then(({ count, size }) => {
|
||||
// Optionally, log any warnings and details.
|
||||
return `${count} files will be precached, totaling ${size} bytes.`;
|
||||
});
|
||||
};
|
||||
buildSW();
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
/* eslint-disable */
|
||||
if ('function' === typeof importScripts) {
|
||||
importScripts(
|
||||
'https://storage.googleapis.com/workbox-cdn/releases/3.5.0/workbox-sw.js'
|
||||
);
|
||||
/* global workbox */
|
||||
if (workbox) {
|
||||
/* injection point for manifest files. */
|
||||
workbox.precaching.precacheAndRoute([]);
|
||||
|
||||
/* custom cache rules*/
|
||||
workbox.routing.registerNavigationRoute('/index.html', {
|
||||
blacklist: [/^\/_/, /\/[^\/]+\.[^\/]+$/],
|
||||
});
|
||||
|
||||
workbox.routing.registerRoute(
|
||||
/\.(?:png|gif|jpg|jpeg)$/,
|
||||
workbox.strategies.cacheFirst({
|
||||
cacheName: 'images',
|
||||
plugins: [
|
||||
new workbox.expiration.Plugin({
|
||||
maxEntries: 60,
|
||||
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
|
||||
}),
|
||||
],
|
||||
})
|
||||
importScripts(
|
||||
'https://storage.googleapis.com/workbox-cdn/releases/3.5.0/workbox-sw.js'
|
||||
);
|
||||
|
||||
}
|
||||
/* global workbox */
|
||||
if (workbox) {
|
||||
/* injection point for manifest files. */
|
||||
workbox.precaching.precacheAndRoute([]);
|
||||
|
||||
/* custom cache rules*/
|
||||
workbox.routing.registerNavigationRoute('/index.html', {
|
||||
blacklist: [/^\/_/, /\/[^\/]+\.[^\/]+$/],
|
||||
});
|
||||
|
||||
workbox.routing.registerRoute(
|
||||
/\.(?:png|gif|jpg|jpeg)$/,
|
||||
workbox.strategies.cacheFirst({
|
||||
cacheName: 'images',
|
||||
plugins: [
|
||||
new workbox.expiration.Plugin({
|
||||
maxEntries: 60,
|
||||
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
|
||||
}),
|
||||
],
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +1,99 @@
|
||||
const puppeteer = require('puppeteer');
|
||||
var should = require('should');
|
||||
var utils = require('./test-utils');
|
||||
const should = require('should');
|
||||
const utils = require('./test-utils');
|
||||
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
let email = utils.generateRandomBusinessEmail();
|
||||
let password = utils.generateRandomString();
|
||||
const email = utils.generateRandomBusinessEmail();
|
||||
const password = utils.generateRandomString();
|
||||
const user = {
|
||||
email,
|
||||
password
|
||||
password,
|
||||
};
|
||||
|
||||
describe('Change Password API', () => {
|
||||
beforeAll(async () => {
|
||||
jest.setTimeout(15000);
|
||||
browser = await puppeteer.launch(utils.puppeteerLaunchConfig);
|
||||
page = await browser.newPage();
|
||||
await page.setUserAgent(
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
|
||||
);
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
afterAll(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
jest.setTimeout(15000);
|
||||
browser = await puppeteer.launch(utils.puppeteerLaunchConfig);
|
||||
page = await browser.newPage();
|
||||
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');
|
||||
});
|
||||
it('Should not allow change of password if password and confirm password do not math', async () => {
|
||||
await page.goto(
|
||||
utils.ACCOUNTS_URL + '/change-password/thisisaWrongRestToken',
|
||||
{ waitUntil: 'networkidle2' }
|
||||
);
|
||||
await page.waitForSelector('#password');
|
||||
await page.click('input[name=password]');
|
||||
await page.type('input[name=password]', user.password);
|
||||
await page.waitForSelector('#confirmPassword');
|
||||
await page.click('input[name=confirmPassword]');
|
||||
await page.type('input[name=confirmPassword]', 'unmatchingPassword');
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector(
|
||||
'#confirmPasswordField > span > span:nth-child(2)'
|
||||
);
|
||||
const html = await page.$eval(
|
||||
'#confirmPasswordField > span > span:nth-child(2)',
|
||||
e => {
|
||||
return e.innerHTML;
|
||||
}
|
||||
);
|
||||
should.exist(html);
|
||||
html.should.containEql('Password and confirm password should match.');
|
||||
}, 160000);
|
||||
|
||||
afterAll(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
it('Should submit if password is less than 8 characters', async () => {
|
||||
await page.goto(
|
||||
utils.ACCOUNTS_URL + '/change-password/thisisaWrongRestToken',
|
||||
{ waitUntil: 'networkidle2' }
|
||||
);
|
||||
await page.waitForSelector('#password');
|
||||
await page.click('input[name=password]');
|
||||
await page.type('input[name=password]', '123456');
|
||||
await page.waitForSelector('#confirmPassword');
|
||||
await page.click('input[name=confirmPassword]');
|
||||
await page.type('input[name=confirmPassword]', '123456');
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#passwordField > span > span:nth-child(1)');
|
||||
const html = await page.$eval(
|
||||
'#passwordField > span > span:nth-child(2)',
|
||||
e => {
|
||||
return e.innerHTML;
|
||||
}
|
||||
);
|
||||
should.exist(html);
|
||||
html.should.containEql('Password should be atleast 8 characters long');
|
||||
}, 160000);
|
||||
|
||||
it('Should not allow change of password if password and confirm password do not math', async () => {
|
||||
await page.goto(utils.ACCOUNTS_URL + '/change-password/thisisaWrongRestToken', { waitUntil: 'networkidle2' });
|
||||
await page.waitForSelector('#password');
|
||||
await page.click('input[name=password]');
|
||||
await page.type('input[name=password]', user.password);
|
||||
await page.waitForSelector('#confirmPassword');
|
||||
await page.click('input[name=confirmPassword]');
|
||||
await page.type('input[name=confirmPassword]', 'unmatchingPassword');
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#confirmPasswordField > span > span:nth-child(2)');
|
||||
const html = await page.$eval('#confirmPasswordField > span > span:nth-child(2)', (e) => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql("Password and confirm password should match.");
|
||||
}, 160000);
|
||||
|
||||
it('Should submit if password is less than 8 characters', async () => {
|
||||
await page.goto(utils.ACCOUNTS_URL + '/change-password/thisisaWrongRestToken', { waitUntil: 'networkidle2' });
|
||||
await page.waitForSelector('#password');
|
||||
await page.click('input[name=password]');
|
||||
await page.type('input[name=password]', '123456');
|
||||
await page.waitForSelector('#confirmPassword');
|
||||
await page.click('input[name=confirmPassword]');
|
||||
await page.type('input[name=confirmPassword]', '123456');
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#passwordField > span > span:nth-child(1)');
|
||||
const html = await page.$eval('#passwordField > span > span:nth-child(2)', (e) => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql("Password should be atleast 8 characters long");
|
||||
}, 160000);
|
||||
|
||||
it('Should submit if password is missing', async () => {
|
||||
await page.goto(utils.ACCOUNTS_URL + '/change-password/thisisaWrongRestToken', { waitUntil: 'networkidle2' });
|
||||
await page.waitForSelector('#password');
|
||||
await page.click('input[name=password]');
|
||||
await page.type('input[name=password]', '');
|
||||
await page.waitForSelector('#confirmPassword');
|
||||
await page.click('input[name=confirmPassword]');
|
||||
await page.type('input[name=confirmPassword]', '123456');
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#passwordField > span > span:nth-child(1)');
|
||||
const html = await page.$eval('#passwordField > span > span:nth-child(2)', (e) => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql("Password is required.");
|
||||
}, 160000);
|
||||
it('Should submit if password is missing', async () => {
|
||||
await page.goto(
|
||||
utils.ACCOUNTS_URL + '/change-password/thisisaWrongRestToken',
|
||||
{ waitUntil: 'networkidle2' }
|
||||
);
|
||||
await page.waitForSelector('#password');
|
||||
await page.click('input[name=password]');
|
||||
await page.type('input[name=password]', '');
|
||||
await page.waitForSelector('#confirmPassword');
|
||||
await page.click('input[name=confirmPassword]');
|
||||
await page.type('input[name=confirmPassword]', '123456');
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#passwordField > span > span:nth-child(1)');
|
||||
const html = await page.$eval(
|
||||
'#passwordField > span > span:nth-child(2)',
|
||||
e => {
|
||||
return e.innerHTML;
|
||||
}
|
||||
);
|
||||
should.exist(html);
|
||||
html.should.containEql('Password is required.');
|
||||
}, 160000);
|
||||
});
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
const puppeteer = require('puppeteer');
|
||||
var should = require('should');
|
||||
var utils = require('./test-utils');
|
||||
var init = require('./test-init');
|
||||
const utils = require('./test-utils');
|
||||
const init = require('./test-init');
|
||||
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
let email = utils.generateRandomBusinessEmail();
|
||||
let password = '1234567890';
|
||||
const email = utils.generateRandomBusinessEmail();
|
||||
const password = '1234567890';
|
||||
const user = {
|
||||
email,
|
||||
password
|
||||
password,
|
||||
};
|
||||
|
||||
describe('Login API', () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.setTimeout(20000);
|
||||
browser = await puppeteer.launch(utils.puppeteerLaunchConfig);
|
||||
page = await browser.newPage();
|
||||
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');
|
||||
await page.setUserAgent(
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -27,7 +27,9 @@ describe('Login API', () => {
|
||||
});
|
||||
|
||||
it('Users cannot login with incorrect credentials', async () => {
|
||||
await page.goto(utils.ACCOUNTS_URL + '/login', { waitUntil: 'networkidle2' });
|
||||
await page.goto(utils.ACCOUNTS_URL + '/login', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#login-button');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', user.email);
|
||||
@@ -35,7 +37,7 @@ describe('Login API', () => {
|
||||
await page.type('input[name=password]', user.password);
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitFor(10000);
|
||||
const html = await page.$eval('#main-body', (e) => {
|
||||
const html = await page.$eval('#main-body', e => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
html.should.containEql('User does not exist.');
|
||||
@@ -45,18 +47,18 @@ describe('Login API', () => {
|
||||
await init.registerUser(user, page);
|
||||
await init.loginUser(user, page);
|
||||
|
||||
var localStorageData = await page.evaluate(() => {
|
||||
let json = {};
|
||||
const localStorageData = await page.evaluate(() => {
|
||||
const json = {};
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
json[key] = localStorage.getItem(key);
|
||||
}
|
||||
return json;
|
||||
});
|
||||
|
||||
|
||||
await page.waitFor(10000);
|
||||
localStorageData.should.have.property('access_token');
|
||||
localStorageData.should.have.property('email', email);
|
||||
page.url().should.containEql(utils.DASHBOARD_URL);
|
||||
}, 160000);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
const puppeteer = require('puppeteer');
|
||||
var should = require('should');
|
||||
var utils = require('./test-utils');
|
||||
var init = require('./test-init');
|
||||
const utils = require('./test-utils');
|
||||
const init = require('./test-init');
|
||||
|
||||
let browser;
|
||||
let page, userCredentials;
|
||||
let page;
|
||||
|
||||
let email = utils.generateRandomBusinessEmail();
|
||||
let password = utils.generateRandomString();
|
||||
const email = utils.generateRandomBusinessEmail();
|
||||
const password = utils.generateRandomString();
|
||||
const user = {
|
||||
email,
|
||||
password
|
||||
password,
|
||||
};
|
||||
|
||||
describe('Registration API', () => {
|
||||
beforeAll(async () => {
|
||||
|
||||
jest.setTimeout(15000);
|
||||
browser = await puppeteer.launch(utils.puppeteerLaunchConfig);
|
||||
page = await browser.newPage();
|
||||
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');
|
||||
await page.setUserAgent(
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -28,7 +28,9 @@ describe('Registration API', () => {
|
||||
|
||||
it('User cannot register with invalid email', async () => {
|
||||
const invalidEmail = 'invalidEmail';
|
||||
await page.goto(utils.ACCOUNTS_URL + '/register', { waitUntil: 'networkidle2' });
|
||||
await page.goto(utils.ACCOUNTS_URL + '/register', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', invalidEmail);
|
||||
@@ -45,15 +47,17 @@ describe('Registration API', () => {
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitFor(1000);
|
||||
|
||||
const html = await page.$eval('#email', (e) => {
|
||||
return e.innerHTML
|
||||
const html = await page.$eval('#email', e => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
html.should.containEql('Email is not valid.')
|
||||
html.should.containEql('Email is not valid.');
|
||||
}, 160000);
|
||||
|
||||
it('User cannot register with personal email', async () => {
|
||||
const personalEmail = 'personalEmail@gmail.com'
|
||||
await page.goto(utils.ACCOUNTS_URL + '/register', { waitUntil: 'networkidle2' });
|
||||
const personalEmail = 'personalEmail@gmail.com';
|
||||
await page.goto(utils.ACCOUNTS_URL + '/register', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', personalEmail);
|
||||
@@ -69,18 +73,18 @@ describe('Registration API', () => {
|
||||
await page.type('input[name=confirmPassword]', user.password);
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitFor(1000);
|
||||
const html = await page.$eval('#email', (e) => {
|
||||
return e.innerHTML
|
||||
const html = await page.$eval('#email', e => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
html.should.containEql('Please enter a business email address.')
|
||||
html.should.containEql('Please enter a business email address.');
|
||||
}, 16000);
|
||||
|
||||
it('Should register User with valid details', async () => {
|
||||
await init.registerUser(user, page);
|
||||
await page.waitFor(15000);
|
||||
const html = await page.$eval('#main-body', (e) => {
|
||||
const html = await page.$eval('#main-body', e => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
html.should.containEql('Activate your Fyipe account');
|
||||
}, 160000);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,55 +1,63 @@
|
||||
/* eslint-disable quotes */
|
||||
|
||||
const puppeteer = require('puppeteer');
|
||||
var should = require('should');
|
||||
var utils = require('./test-utils');
|
||||
var init = require('./test-init');
|
||||
const should = require('should');
|
||||
const utils = require('./test-utils');
|
||||
const init = require('./test-init');
|
||||
|
||||
let browser;
|
||||
let page, userCredentials;
|
||||
let page;
|
||||
|
||||
let email = utils.generateRandomBusinessEmail();
|
||||
let password = utils.generateRandomString();
|
||||
const email = utils.generateRandomBusinessEmail();
|
||||
const password = utils.generateRandomString();
|
||||
const user = { email, password };
|
||||
|
||||
describe('Resend Verification API', () => {
|
||||
beforeAll(async () => {
|
||||
jest.setTimeout(30000);
|
||||
browser = await puppeteer.launch(utils.puppeteerLaunchConfig);
|
||||
page = await browser.newPage();
|
||||
await page.setUserAgent(
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
|
||||
);
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
afterAll(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
jest.setTimeout(30000);
|
||||
browser = await puppeteer.launch(utils.puppeteerLaunchConfig);
|
||||
page = await browser.newPage();
|
||||
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');
|
||||
});
|
||||
it('Should not resend verification token if a user associated with the email does not exist', async () => {
|
||||
await page.goto(utils.ACCOUNTS_URL + '/user-verify/resend', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', 'invalid@email.com');
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#error-msg');
|
||||
const html = await page.$eval('#error-msg', e => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql('No user associated with this account');
|
||||
}, 160000);
|
||||
|
||||
afterAll(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('Should not resend verification token if a user associated with the email does not exist', async () => {
|
||||
await page.goto(utils.ACCOUNTS_URL + '/user-verify/resend', { waitUntil: 'networkidle2' });
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', 'invalid@email.com');
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#error-msg');
|
||||
const html = await page.$eval('#error-msg', (e) => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql("No user associated with this account");
|
||||
}, 160000);
|
||||
|
||||
it('Should resend verification token successfully', async () => {
|
||||
await init.registerUser(user, page);
|
||||
await page.goto(utils.ACCOUNTS_URL + '/user-verify/resend', { waitUntil: 'networkidle2' });
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', email);
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#resend-verification-success');
|
||||
const html = await page.$eval('#resend-verification-success', (e) => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql(" An email is on its way to you with new verification link. Please don't forget to check spam.");
|
||||
}, 160000);
|
||||
it('Should resend verification token successfully', async () => {
|
||||
await init.registerUser(user, page);
|
||||
await page.goto(utils.ACCOUNTS_URL + '/user-verify/resend', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', email);
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#resend-verification-success');
|
||||
const html = await page.$eval('#resend-verification-success', e => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql(
|
||||
" An email is on its way to you with new verification link. Please don't forget to check spam."
|
||||
);
|
||||
}, 160000);
|
||||
});
|
||||
|
||||
@@ -1,58 +1,66 @@
|
||||
/* eslint-disable quotes */
|
||||
|
||||
const puppeteer = require('puppeteer');
|
||||
var should = require('should');
|
||||
var utils = require('./test-utils');
|
||||
var init = require('./test-init');
|
||||
const should = require('should');
|
||||
const utils = require('./test-utils');
|
||||
const init = require('./test-init');
|
||||
|
||||
let browser;
|
||||
let page, userCredentials;
|
||||
let page;
|
||||
|
||||
let email = utils.generateRandomBusinessEmail();
|
||||
let password = utils.generateRandomString();
|
||||
const email = utils.generateRandomBusinessEmail();
|
||||
const password = utils.generateRandomString();
|
||||
const user = {
|
||||
email,
|
||||
password
|
||||
password,
|
||||
};
|
||||
|
||||
describe('Reset Password API', () => {
|
||||
beforeAll(async () => {
|
||||
jest.setTimeout(15000);
|
||||
browser = await puppeteer.launch(utils.puppeteerLaunchConfig);
|
||||
page = await browser.newPage();
|
||||
await page.setUserAgent(
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
|
||||
);
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
afterAll(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
jest.setTimeout(15000);
|
||||
browser = await puppeteer.launch(utils.puppeteerLaunchConfig);
|
||||
page = await browser.newPage();
|
||||
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');
|
||||
});
|
||||
it('Should reset password successfully', async () => {
|
||||
await init.registerUser(user, page);
|
||||
await page.goto(utils.ACCOUNTS_URL + '/forgot-password', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', email);
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#reset-password-success');
|
||||
const html = await page.$eval('#reset-password-success', e => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql(
|
||||
" An email is on its way to you. Follow the instructions to reset your password. Please don't forget to check spam. "
|
||||
);
|
||||
}, 160000);
|
||||
|
||||
afterAll(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('Should reset password successfully', async () => {
|
||||
await init.registerUser(user, page)
|
||||
await page.goto(utils.ACCOUNTS_URL + '/forgot-password', { waitUntil: 'networkidle2' });
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', email);
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#reset-password-success');
|
||||
const html = await page.$eval('#reset-password-success', (e) => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql(" An email is on its way to you. Follow the instructions to reset your password. Please don't forget to check spam. ");
|
||||
}, 160000);
|
||||
|
||||
it('User cannot reset password with non-existing email', async () => {
|
||||
await page.goto(utils.ACCOUNTS_URL + '/forgot-password', { waitUntil: 'networkidle2' });
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', utils.generateWrongEmail());
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#error-msg');
|
||||
const html = await page.$eval('#error-msg', (e) => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql('User does not exist.');
|
||||
}, 160000);
|
||||
});
|
||||
it('User cannot reset password with non-existing email', async () => {
|
||||
await page.goto(utils.ACCOUNTS_URL + '/forgot-password', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', utils.generateWrongEmail());
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('#error-msg');
|
||||
const html = await page.$eval('#error-msg', e => {
|
||||
return e.innerHTML;
|
||||
});
|
||||
should.exist(html);
|
||||
html.should.containEql('User does not exist.');
|
||||
}, 160000);
|
||||
});
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
const utils = require('./test-utils');
|
||||
const cards = ['4000056655665556', '4242424242424242', '5555555555554444', '2223003122003222', '5200828282828210', '5105105105105100']
|
||||
module.exports = {
|
||||
const cards = [
|
||||
'4000056655665556',
|
||||
'4242424242424242',
|
||||
'5555555555554444',
|
||||
'2223003122003222',
|
||||
'5200828282828210',
|
||||
'5105105105105100',
|
||||
];
|
||||
module.exports = {
|
||||
/**
|
||||
*
|
||||
* @param { ObjectConstructor } user
|
||||
* @param { string } page
|
||||
*
|
||||
* @param { ObjectConstructor } user
|
||||
* @param { string } page
|
||||
* @description Registers a new user.
|
||||
* @returns { void }
|
||||
*/
|
||||
registerUser: async function (user, page){
|
||||
registerUser: async function(user, page) {
|
||||
const { email } = user;
|
||||
let frame, elementHandle;
|
||||
await page.goto(utils.ACCOUNTS_URL + '/register', { waitUntil: 'networkidle2' });
|
||||
await page.goto(utils.ACCOUNTS_URL + '/register', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#email');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', email);
|
||||
@@ -36,22 +45,26 @@ module.exports = {
|
||||
elementHandle = await page.$('iframe[name=__privateStripeFrame5]');
|
||||
frame = await elementHandle.contentFrame();
|
||||
await frame.waitForSelector('input[name=cardnumber]');
|
||||
await frame.type('input[name=cardnumber]', cards[Math.floor(Math.random() * cards.length)], {
|
||||
delay:50
|
||||
});
|
||||
await frame.type(
|
||||
'input[name=cardnumber]',
|
||||
cards[Math.floor(Math.random() * cards.length)],
|
||||
{
|
||||
delay: 50,
|
||||
}
|
||||
);
|
||||
|
||||
elementHandle = await page.$('iframe[name=__privateStripeFrame6]');
|
||||
frame = await elementHandle.contentFrame();
|
||||
await frame.waitForSelector('input[name=cvc]');
|
||||
await frame.type('input[name=cvc]', '123', {
|
||||
delay:50
|
||||
delay: 50,
|
||||
});
|
||||
|
||||
elementHandle = await page.$('iframe[name=__privateStripeFrame7]');
|
||||
frame = await elementHandle.contentFrame();
|
||||
await frame.waitForSelector('input[name=exp-date]');
|
||||
await frame.type('input[name=exp-date]', '11/23', {
|
||||
delay:50
|
||||
delay: 50,
|
||||
});
|
||||
await page.click('input[name=address1]');
|
||||
await page.type('input[name=address1]', utils.user.address.streetA);
|
||||
@@ -63,17 +76,18 @@ module.exports = {
|
||||
await page.type('input[name=state]', utils.user.address.state);
|
||||
await page.click('input[name=zipCode]');
|
||||
await page.type('input[name=zipCode]', utils.user.address.zipcode);
|
||||
await page.select('#country', 'India')
|
||||
await page.waitFor(60000); //wait for a second because of stripe rate limits.
|
||||
await page.select('#country', 'India');
|
||||
await page.waitFor(60000); //wait for a second because of stripe rate limits.
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitForSelector('.request-reset-step', {
|
||||
timeout: 60000
|
||||
})
|
||||
|
||||
timeout: 60000,
|
||||
});
|
||||
},
|
||||
loginUser: async function (user, page){
|
||||
loginUser: async function(user, page) {
|
||||
const { email, password } = user;
|
||||
await page.goto(utils.ACCOUNTS_URL + '/login', { waitUntil: 'networkidle2' });
|
||||
await page.goto(utils.ACCOUNTS_URL + '/login', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.waitForSelector('#login-button');
|
||||
await page.click('input[name=email]');
|
||||
await page.type('input[name=email]', email);
|
||||
@@ -81,5 +95,5 @@ module.exports = {
|
||||
await page.type('input[name=password]', password);
|
||||
await page.click('button[type=submit]');
|
||||
await page.waitFor(10000);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -5,36 +5,49 @@ const DASHBOARD_URL = 'http://localhost:3000';
|
||||
|
||||
const puppeteerLaunchConfig = {
|
||||
args: [
|
||||
'--proxy-server=',
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-accelerated-2d-canvas',
|
||||
'--disable-gpu',
|
||||
'--window-size=1920x1080',
|
||||
'--disable-background-timer-throttling',
|
||||
'--disable-backgrounding-occluded-windows',
|
||||
'--disable-renderer-backgrounding',
|
||||
'--disable-web-security'
|
||||
'--proxy-server=',
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-accelerated-2d-canvas',
|
||||
'--disable-gpu',
|
||||
'--window-size=1920x1080',
|
||||
'--disable-background-timer-throttling',
|
||||
'--disable-backgrounding-occluded-windows',
|
||||
'--disable-renderer-backgrounding',
|
||||
'--disable-web-security',
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const user = faker.helpers.createCard();
|
||||
|
||||
function generateWrongEmail() {
|
||||
return Math.random().toString(36).substring(8) + '@' + Math.random().toString(24).substring(8) + '.com';
|
||||
return (
|
||||
Math.random()
|
||||
.toString(36)
|
||||
.substring(8) +
|
||||
'@' +
|
||||
Math.random()
|
||||
.toString(24)
|
||||
.substring(8) +
|
||||
'.com'
|
||||
);
|
||||
}
|
||||
|
||||
function generateRandomString(){
|
||||
return Math.random().toString(36).substring(10)
|
||||
function generateRandomString() {
|
||||
return Math.random()
|
||||
.toString(36)
|
||||
.substring(10);
|
||||
}
|
||||
|
||||
function generateRandomBusinessEmail(){
|
||||
return `${Math.random().toString(36).substring(7)}@${Math.random().toString(36).substring(5)}.com`;
|
||||
function generateRandomBusinessEmail() {
|
||||
return `${Math.random()
|
||||
.toString(36)
|
||||
.substring(7)}@${Math.random()
|
||||
.toString(36)
|
||||
.substring(5)}.com`;
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
ACCOUNTS_URL,
|
||||
DASHBOARD_URL,
|
||||
@@ -42,5 +55,5 @@ module.exports = {
|
||||
user,
|
||||
generateWrongEmail,
|
||||
generateRandomString,
|
||||
generateRandomBusinessEmail
|
||||
generateRandomBusinessEmail,
|
||||
};
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
# fyipe-admin-dashboard
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ const app = express();
|
||||
app.use(express.static(path.join(__dirname, 'build')));
|
||||
|
||||
app.get('/*', function(req, res) {
|
||||
res.sendFile(path.join(__dirname, 'build', 'index.html'));
|
||||
res.sendFile(path.join(__dirname, 'build', 'index.html'));
|
||||
});
|
||||
|
||||
app.listen(3100);
|
||||
app.listen(3100);
|
||||
|
||||
37042
admin-dashboard/package-lock.json
generated
37042
admin-dashboard/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,86 +1,86 @@
|
||||
{
|
||||
"name": "fyipe-admin-dashboard",
|
||||
"version": "3.0.1891",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"acorn": "^7.1.0",
|
||||
"axios": "^0.18.0",
|
||||
"browserslist": "^4.6.1",
|
||||
"card-validator": "^6.2.0",
|
||||
"clipboard": "^2.0.1",
|
||||
"express": "^4.16.4",
|
||||
"file-saver": "^2.0.1",
|
||||
"font-awesome": "^4.7.0",
|
||||
"fuzzy-match-utils": "^1.3.0",
|
||||
"history": "^4.7.2",
|
||||
"jest": "^24.7.1",
|
||||
"js-uuid": "0.0.6",
|
||||
"loadable-components": "^2.2.3",
|
||||
"mixpanel-browser": "^2.22.3",
|
||||
"moment": "^2.22.2",
|
||||
"prop-types": "^15.6.1",
|
||||
"react": "^16.5.2",
|
||||
"react-click-outside": "github:tj/react-click-outside",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-frontload": "^1.0.3",
|
||||
"react-ga": "^2.5.3",
|
||||
"react-json-view": "^1.19.1",
|
||||
"react-mixpanel": "0.0.11",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-router-redux": "^4.0.8",
|
||||
"react-scripts": "^3.4.0",
|
||||
"react-select-fyipe": "^2.1.8",
|
||||
"react-widgets": "^4.4.9",
|
||||
"redux": "^3.7.2",
|
||||
"redux-form": "^7.3.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"sane-email-validation": "^1.1.0",
|
||||
"universal-cookie": "^4.0.0",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"fix-lint": "eslint . --fix",
|
||||
"dev": "PORT=3100 react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest src/test/puppeteer/index.test.js",
|
||||
"start": "node index.js",
|
||||
"audit": "npm-audit-ci-wrapper --threshold=low",
|
||||
"dep-check": "depcheck ./ --skip-missing=true --ignores='eslint,babel-*,browserslist,loadable-components,js-uuid,acorn'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"depcheck": "^0.9.2",
|
||||
"eslint": "^6.1.0",
|
||||
"jest-localstorage-mock": "^2.2.0",
|
||||
"npm-audit-ci-wrapper": "^2.4.3",
|
||||
"redux-logger": "^3.0.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"
|
||||
]
|
||||
}
|
||||
"name": "fyipe-admin-dashboard",
|
||||
"version": "3.0.1891",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"acorn": "^7.1.0",
|
||||
"axios": "^0.18.0",
|
||||
"browserslist": "^4.6.1",
|
||||
"card-validator": "^6.2.0",
|
||||
"clipboard": "^2.0.1",
|
||||
"express": "^4.16.4",
|
||||
"file-saver": "^2.0.1",
|
||||
"font-awesome": "^4.7.0",
|
||||
"fuzzy-match-utils": "^1.3.0",
|
||||
"history": "^4.7.2",
|
||||
"jest": "^24.7.1",
|
||||
"js-uuid": "0.0.6",
|
||||
"loadable-components": "^2.2.3",
|
||||
"mixpanel-browser": "^2.22.3",
|
||||
"moment": "^2.22.2",
|
||||
"prop-types": "^15.6.1",
|
||||
"react": "^16.5.2",
|
||||
"react-click-outside": "github:tj/react-click-outside",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-frontload": "^1.0.3",
|
||||
"react-ga": "^2.5.3",
|
||||
"react-json-view": "^1.19.1",
|
||||
"react-mixpanel": "0.0.11",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-router-redux": "^4.0.8",
|
||||
"react-scripts": "^3.4.0",
|
||||
"react-select-fyipe": "^2.1.8",
|
||||
"react-widgets": "^4.4.9",
|
||||
"redux": "^3.7.2",
|
||||
"redux-form": "^7.3.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"sane-email-validation": "^1.1.0",
|
||||
"universal-cookie": "^4.0.0",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"fix-lint": "eslint . --fix",
|
||||
"dev": "PORT=3100 react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest src/test/puppeteer/index.test.js",
|
||||
"start": "node index.js",
|
||||
"audit": "npm-audit-ci-wrapper --threshold=low",
|
||||
"dep-check": "depcheck ./ --skip-missing=true --ignores='eslint,babel-*,browserslist,loadable-components,js-uuid,acorn'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"depcheck": "^0.9.2",
|
||||
"eslint": "^6.1.0",
|
||||
"jest-localstorage-mock": "^2.2.0",
|
||||
"npm-audit-ci-wrapper": "^2.4.3",
|
||||
"redux-logger": "^3.0.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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,57 +11,55 @@ import Cookies from 'universal-cookie';
|
||||
import 'font-awesome/css/font-awesome.min.css';
|
||||
|
||||
if (!isServer) {
|
||||
history.listen(location => {
|
||||
ReactGA.set({ page: location.pathname });
|
||||
ReactGA.pageview(location.pathname);
|
||||
});
|
||||
history.listen(location => {
|
||||
ReactGA.set({ page: location.pathname });
|
||||
ReactGA.pageview(location.pathname);
|
||||
});
|
||||
}
|
||||
|
||||
const cookies = new Cookies();
|
||||
|
||||
const userData = cookies.get('admin-data');
|
||||
if (userData !== undefined){
|
||||
User.setUserId(userData.id);
|
||||
User.setAccessToken(userData.tokens.jwtAccessToken);
|
||||
User.setEmail(userData.email);
|
||||
User.setName(userData.name);
|
||||
if (userData !== undefined) {
|
||||
User.setUserId(userData.id);
|
||||
User.setAccessToken(userData.tokens.jwtAccessToken);
|
||||
User.setEmail(userData.email);
|
||||
User.setName(userData.name);
|
||||
}
|
||||
cookies.remove('admin-data', {domain: DOMAIN_URL });
|
||||
cookies.remove('admin-data', { domain: DOMAIN_URL });
|
||||
|
||||
if (!User.isLoggedIn()){
|
||||
window.location = ACCOUNTS_URL;
|
||||
if (!User.isLoggedIn()) {
|
||||
window.location = ACCOUNTS_URL;
|
||||
}
|
||||
|
||||
const App = () => (
|
||||
<div style={{ height: '100%' }}>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
{allRoutes.filter(route => route.visible).map((route, index) => {
|
||||
return (
|
||||
<Route
|
||||
exact
|
||||
path={route.path}
|
||||
key={index}
|
||||
component={(route.component)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
<Route
|
||||
path={'/:404_path'}
|
||||
key={'404'}
|
||||
component={NotFound}
|
||||
/>
|
||||
<Redirect to="/users" />
|
||||
</Switch>
|
||||
</Router>
|
||||
<BackboneModals />
|
||||
</div>
|
||||
<div style={{ height: '100%' }}>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
{allRoutes
|
||||
.filter(route => route.visible)
|
||||
.map((route, index) => {
|
||||
return (
|
||||
<Route
|
||||
exact
|
||||
path={route.path}
|
||||
key={index}
|
||||
component={route.component}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Route path={'/:404_path'} key={'404'} component={NotFound} />
|
||||
<Redirect to="/users" />
|
||||
</Switch>
|
||||
</Router>
|
||||
<BackboneModals />
|
||||
</div>
|
||||
);
|
||||
|
||||
App.displayName = 'App'
|
||||
App.displayName = 'App';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return state.login;
|
||||
return state.login;
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(App);
|
||||
|
||||
@@ -4,105 +4,103 @@ import errors from '../errors';
|
||||
|
||||
// Fetch All Audit Logs
|
||||
export const fetchAuditLogsRequest = () => {
|
||||
return {
|
||||
type: types.FETCH_AUDITLOGS_REQUEST
|
||||
};
|
||||
return {
|
||||
type: types.FETCH_AUDITLOGS_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchAuditLogsSuccess = auditLogs => {
|
||||
return {
|
||||
type: types.FETCH_AUDITLOGS_SUCCESS,
|
||||
payload: auditLogs
|
||||
};
|
||||
return {
|
||||
type: types.FETCH_AUDITLOGS_SUCCESS,
|
||||
payload: auditLogs,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchAuditLogsError = error => {
|
||||
return {
|
||||
type: types.FETCH_AUDITLOGS_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.FETCH_AUDITLOGS_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchAuditLogs = (skip, limit) => async dispatch => {
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
|
||||
dispatch(fetchAuditLogsRequest());
|
||||
dispatch(fetchAuditLogsRequest());
|
||||
|
||||
try {
|
||||
const response = await getApi(
|
||||
`audit-logs?skip=${skip}&limit=${limit}`
|
||||
);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await getApi(`audit-logs?skip=${skip}&limit=${limit}`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(fetchAuditLogsSuccess(data));
|
||||
dispatch(fetchAuditLogsSuccess(data));
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchAuditLogsError(errors(errorMsg)));
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchAuditLogsError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
// Search Audit Logs.
|
||||
export const searchAuditLogsRequest = () => {
|
||||
return {
|
||||
type: types.SEARCH_AUDITLOGS_REQUEST
|
||||
};
|
||||
return {
|
||||
type: types.SEARCH_AUDITLOGS_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchAuditLogsSuccess = auditLogs => {
|
||||
return {
|
||||
type: types.SEARCH_AUDITLOGS_SUCCESS,
|
||||
payload: auditLogs
|
||||
};
|
||||
return {
|
||||
type: types.SEARCH_AUDITLOGS_SUCCESS,
|
||||
payload: auditLogs,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchAuditLogsError = error => {
|
||||
return {
|
||||
type: types.SEARCH_AUDITLOGS_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
return {
|
||||
type: types.SEARCH_AUDITLOGS_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchAuditLogs = (filter, skip, limit) => async dispatch => {
|
||||
const values = {
|
||||
filter
|
||||
};
|
||||
const values = {
|
||||
filter,
|
||||
};
|
||||
|
||||
dispatch(searchAuditLogsRequest());
|
||||
dispatch(searchAuditLogsRequest());
|
||||
|
||||
try {
|
||||
const response = await postApi(
|
||||
`audit-logs/search?skip=${skip}&limit=${limit}`,
|
||||
values
|
||||
);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await postApi(
|
||||
`audit-logs/search?skip=${skip}&limit=${limit}`,
|
||||
values
|
||||
);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(searchAuditLogsSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
dispatch(searchAuditLogsSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(searchAuditLogsError(errors(errorMsg)));
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(searchAuditLogsError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import * as types from '../constants/logout'
|
||||
import * as types from '../constants/logout';
|
||||
// Three possible states for our logout process as well.
|
||||
// Since we are using JWTs, we just need to remove the token
|
||||
// from localStorage. These actions are more useful if we
|
||||
// were calling the API to log the user out
|
||||
|
||||
export const requestLogout = () => {
|
||||
return {
|
||||
type: types.LOGOUT_REQUEST,
|
||||
isFetching: true,
|
||||
isAuthenticated: true
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: types.LOGOUT_REQUEST,
|
||||
isFetching: true,
|
||||
isAuthenticated: true,
|
||||
};
|
||||
};
|
||||
|
||||
export const receiveLogout = () => {
|
||||
return {
|
||||
type: types.LOGOUT_SUCCESS,
|
||||
isFetching: false,
|
||||
isAuthenticated: false
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: types.LOGOUT_SUCCESS,
|
||||
isFetching: false,
|
||||
isAuthenticated: false,
|
||||
};
|
||||
};
|
||||
|
||||
// Logs the user out
|
||||
export const logoutUser = () => dispatch => {
|
||||
dispatch(requestLogout())
|
||||
localStorage.removeItem('id_token')
|
||||
localStorage.removeItem('access_token')
|
||||
dispatch(receiveLogout())
|
||||
}
|
||||
dispatch(requestLogout());
|
||||
localStorage.removeItem('id_token');
|
||||
localStorage.removeItem('access_token');
|
||||
dispatch(receiveLogout());
|
||||
};
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import * as types from '../constants/modal'
|
||||
import * as types from '../constants/modal';
|
||||
|
||||
export const openModal = obj => {
|
||||
return {
|
||||
type: types.OPEN_MODAL,
|
||||
payload: obj
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.OPEN_MODAL,
|
||||
payload: obj,
|
||||
};
|
||||
};
|
||||
export const closeModal = obj => {
|
||||
return {
|
||||
type: types.CLOSE_MODAL,
|
||||
payload: obj
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
type: types.CLOSE_MODAL,
|
||||
payload: obj,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import * as types from '../constants/notification'
|
||||
import * as types from '../constants/notification';
|
||||
|
||||
export const openNotificationMenu = () => {
|
||||
return {
|
||||
type: types.OPEN_NOTIFICATION_MENU
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.OPEN_NOTIFICATION_MENU,
|
||||
};
|
||||
};
|
||||
export const closeNotificationMenu = error => {
|
||||
return {
|
||||
type: types.CLOSE_NOTIFICATION_MENU,
|
||||
payload : error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.CLOSE_NOTIFICATION_MENU,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {getApi, deleteApi, postApi} from '../api';
|
||||
import { getApi, deleteApi, postApi } from '../api';
|
||||
import * as types from '../constants/probe';
|
||||
import errors from '../errors';
|
||||
|
||||
@@ -7,21 +7,21 @@ import errors from '../errors';
|
||||
export function probeRequest(promise) {
|
||||
return {
|
||||
type: types.PROBE_REQUEST,
|
||||
payload: promise
|
||||
payload: promise,
|
||||
};
|
||||
}
|
||||
|
||||
export function probeError(error) {
|
||||
return {
|
||||
type: types.PROBE_FAILED,
|
||||
payload: error
|
||||
payload: error,
|
||||
};
|
||||
}
|
||||
|
||||
export function probeSuccess(probes) {
|
||||
return {
|
||||
type: types.PROBE_SUCCESS,
|
||||
payload: probes
|
||||
payload: probes,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,142 +36,140 @@ export function getProbes(skip = 0, limit = 10) {
|
||||
skip = parseInt(skip);
|
||||
limit = parseInt(limit);
|
||||
|
||||
return function (dispatch) {
|
||||
return function(dispatch) {
|
||||
let promise = null;
|
||||
promise = getApi(`probe/?skip=${skip}&limit=${limit}`);
|
||||
promise = getApi(`probe/?skip=${skip}&limit=${limit}`);
|
||||
dispatch(probeRequest(promise));
|
||||
|
||||
promise.then(function (probes) {
|
||||
probes.data.skip = skip || 0;
|
||||
probes.data.limit = limit || 10;
|
||||
dispatch(probeSuccess(probes.data));
|
||||
}, function (error) {
|
||||
if (error && error.response && error.response.data)
|
||||
error = error.response.data;
|
||||
if (error && error.data) {
|
||||
error = error.data;
|
||||
promise.then(
|
||||
function(probes) {
|
||||
probes.data.skip = skip || 0;
|
||||
probes.data.limit = limit || 10;
|
||||
dispatch(probeSuccess(probes.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(probeError(errors(error)));
|
||||
}
|
||||
if (error && error.message) {
|
||||
error = error.message;
|
||||
}
|
||||
else {
|
||||
error = 'Network Error';
|
||||
}
|
||||
dispatch(probeError(errors(error)));
|
||||
});
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
//Delete project
|
||||
export const deleteProbeRequest = () => {
|
||||
return {
|
||||
type: types.DELETE_PROBE_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_PROBE_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteProbeReset = () => {
|
||||
return {
|
||||
type: types.DELETE_PROBE_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_PROBE_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteProbeSuccess = probeId => {
|
||||
return {
|
||||
type: types.DELETE_PROBE_SUCCESS,
|
||||
payload: probeId
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_PROBE_SUCCESS,
|
||||
payload: probeId,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteProbeError = error => {
|
||||
return {
|
||||
type: types.DELETE_PROBE_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_PROBE_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to delete a probe
|
||||
export const deleteProbe = probeId => async (dispatch) => {
|
||||
export const deleteProbe = probeId => async dispatch => {
|
||||
dispatch(deleteProbeRequest());
|
||||
|
||||
dispatch(deleteProbeRequest());
|
||||
|
||||
try{
|
||||
const response = await deleteApi(`probe/${probeId}`);
|
||||
dispatch(deleteProbeSuccess(probeId));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(deleteProbeError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await deleteApi(`probe/${probeId}`);
|
||||
dispatch(deleteProbeSuccess(probeId));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(deleteProbeError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Delete project
|
||||
export const addProbeRequest = () => {
|
||||
return {
|
||||
type: types.ADD_PROBE_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_PROBE_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const addProbeReset = () => {
|
||||
return {
|
||||
type: types.ADD_PROBE_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_PROBE_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const addProbeSuccess = probeId => {
|
||||
return {
|
||||
type: types.ADD_PROBE_SUCCESS,
|
||||
payload: probeId
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_PROBE_SUCCESS,
|
||||
payload: probeId,
|
||||
};
|
||||
};
|
||||
|
||||
export const addProbeError = error => {
|
||||
return {
|
||||
type: types.ADD_PROBE_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_PROBE_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
export function resetAddProbe() {
|
||||
return function (dispatch) {
|
||||
return function(dispatch) {
|
||||
dispatch(addProbeReset());
|
||||
};
|
||||
}
|
||||
|
||||
// Calls the API to add a probe
|
||||
export const addProbe = (probeKey,probeName) => async (dispatch) => {
|
||||
export const addProbe = (probeKey, probeName) => async dispatch => {
|
||||
dispatch(addProbeRequest());
|
||||
|
||||
dispatch(addProbeRequest());
|
||||
|
||||
try{
|
||||
const response = await postApi('probe/',{probeKey,probeName});
|
||||
try {
|
||||
const response = await postApi('probe/', { probeKey, probeName });
|
||||
const data = response.data;
|
||||
dispatch(addProbeSuccess(data));
|
||||
return 'ok';
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(addProbeError(errors(errorMsg)));
|
||||
return 'error';
|
||||
}
|
||||
}
|
||||
dispatch(addProbeSuccess(data));
|
||||
return 'ok';
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(addProbeError(errors(errorMsg)));
|
||||
return 'error';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import * as types from '../constants/profile';
|
||||
|
||||
export const showProfileMenu = () => {
|
||||
return {
|
||||
type: types.SHOW_PROFILE_MENU,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SHOW_PROFILE_MENU,
|
||||
};
|
||||
};
|
||||
|
||||
export const hideProfileMenu = error => {
|
||||
return {
|
||||
type: types.HIDE_PROFILE_MENU,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.HIDE_PROFILE_MENU,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,539 +1,532 @@
|
||||
import { getApi, putApi, deleteApi, postApi } from '../api';
|
||||
import * as types from '../constants/project';
|
||||
import errors from '../errors'
|
||||
import errors from '../errors';
|
||||
|
||||
// Fetch Projects
|
||||
// Fetch Projects
|
||||
|
||||
export const fetchProjectsRequest = () => {
|
||||
export const fetchProjectsRequest = () => {
|
||||
return {
|
||||
type: types.FETCH_PROJECTS_REQUEST,
|
||||
}
|
||||
}
|
||||
type: types.FETCH_PROJECTS_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchProjectsSuccess = projects => {
|
||||
export const fetchProjectsSuccess = projects => {
|
||||
return {
|
||||
type: types.FETCH_PROJECTS_SUCCESS,
|
||||
payload: projects,
|
||||
}
|
||||
}
|
||||
type: types.FETCH_PROJECTS_SUCCESS,
|
||||
payload: projects,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchProjectsError = error => {
|
||||
export const fetchProjectsError = error => {
|
||||
return {
|
||||
type: types.FETCH_PROJECTS_FAILURE,
|
||||
payload: error,
|
||||
}
|
||||
}
|
||||
type: types.FETCH_PROJECTS_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to fetch all projects.
|
||||
export const fetchProjects = (skip, limit) => async (dispatch) => {
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
export const fetchProjects = (skip, limit) => async dispatch => {
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
|
||||
dispatch(fetchProjectsRequest())
|
||||
dispatch(fetchProjectsRequest());
|
||||
|
||||
try{
|
||||
const response = await getApi(`project/projects/allProjects?skip=${skip}&limit=${limit}`);
|
||||
try {
|
||||
const response = await getApi(
|
||||
`project/projects/allProjects?skip=${skip}&limit=${limit}`
|
||||
);
|
||||
|
||||
dispatch(fetchProjectsSuccess(response.data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchProjectsError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(fetchProjectsSuccess(response.data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchProjectsError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchProjectRequest = () => {
|
||||
return {
|
||||
type: types.FETCH_PROJECT_REQUEST
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_PROJECT_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchProjectSuccess = project => {
|
||||
return {
|
||||
type: types.FETCH_PROJECT_SUCCESS,
|
||||
payload: project
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_PROJECT_SUCCESS,
|
||||
payload: project,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchProjectError = error => {
|
||||
return {
|
||||
type: types.FETCH_PROJECT_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_PROJECT_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to fetch a project.
|
||||
export const fetchProject = projectId => async (dispatch) => {
|
||||
dispatch(fetchProjectRequest());
|
||||
export const fetchProject = projectId => async dispatch => {
|
||||
dispatch(fetchProjectRequest());
|
||||
|
||||
try{
|
||||
const response = await getApi(`project/projects/${projectId}`);
|
||||
const projects = response.data;
|
||||
try {
|
||||
const response = await getApi(`project/projects/${projectId}`);
|
||||
const projects = response.data;
|
||||
|
||||
dispatch(fetchProjectSuccess(projects));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchProjectError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(fetchProjectSuccess(projects));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchProjectError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchUserProjectsRequest = () => {
|
||||
return {
|
||||
type: types.FETCH_USER_PROJECTS_REQUEST
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USER_PROJECTS_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchUserProjectsSuccess = users => {
|
||||
return {
|
||||
type: types.FETCH_USER_PROJECTS_SUCCESS,
|
||||
payload: users
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USER_PROJECTS_SUCCESS,
|
||||
payload: users,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchUserProjectsError = error => {
|
||||
return {
|
||||
type: types.FETCH_USER_PROJECTS_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USER_PROJECTS_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to fetch all user projects.
|
||||
export const fetchUserProjects = (userId, skip, limit) => async (dispatch) => {
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
export const fetchUserProjects = (userId, skip, limit) => async dispatch => {
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
|
||||
dispatch(fetchUserProjectsRequest());
|
||||
dispatch(fetchUserProjectsRequest());
|
||||
|
||||
try{
|
||||
const response = await getApi(`project/projects/user/${userId}?skip=${skip}&limit=${limit}`);
|
||||
const users = response.data;
|
||||
try {
|
||||
const response = await getApi(
|
||||
`project/projects/user/${userId}?skip=${skip}&limit=${limit}`
|
||||
);
|
||||
const users = response.data;
|
||||
|
||||
dispatch(fetchUserProjectsSuccess(users));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchUserProjectsError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(fetchUserProjectsSuccess(users));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchUserProjectsError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Delete project
|
||||
export const deleteProjectRequest = () => {
|
||||
return {
|
||||
type: types.DELETE_PROJECT_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_PROJECT_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteProjectReset = () => {
|
||||
return {
|
||||
type: types.DELETE_PROJECT_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_PROJECT_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteProjectSuccess = project => {
|
||||
return {
|
||||
type: types.DELETE_PROJECT_SUCCESS,
|
||||
payload: project
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_PROJECT_SUCCESS,
|
||||
payload: project,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteProjectError = error => {
|
||||
return {
|
||||
type: types.DELETE_PROJECT_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_PROJECT_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to delete a project
|
||||
export const deleteProject = projectId => async (dispatch) => {
|
||||
export const deleteProject = projectId => async dispatch => {
|
||||
dispatch(deleteProjectRequest());
|
||||
|
||||
dispatch(deleteProjectRequest());
|
||||
try {
|
||||
const response = await deleteApi(`project/${projectId}/deleteProject`);
|
||||
const data = response.data;
|
||||
|
||||
try{
|
||||
const response = await deleteApi(`project/${projectId}/deleteProject`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(deleteProjectSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(deleteProjectError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(deleteProjectSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(deleteProjectError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Block project
|
||||
export const blockProjectRequest = () => {
|
||||
return {
|
||||
type: types.BLOCK_PROJECT_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.BLOCK_PROJECT_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const blockProjectReset = () => {
|
||||
return {
|
||||
type: types.BLOCK_PROJECT_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.BLOCK_PROJECT_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const blockProjectSuccess = project => {
|
||||
return {
|
||||
type: types.BLOCK_PROJECT_SUCCESS,
|
||||
payload: project
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.BLOCK_PROJECT_SUCCESS,
|
||||
payload: project,
|
||||
};
|
||||
};
|
||||
|
||||
export const blockProjectError = error => {
|
||||
return {
|
||||
type: types.BLOCK_PROJECT_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.BLOCK_PROJECT_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to block a project
|
||||
export const blockProject = projectId => async (dispatch) => {
|
||||
export const blockProject = projectId => async dispatch => {
|
||||
dispatch(blockProjectRequest());
|
||||
|
||||
dispatch(blockProjectRequest());
|
||||
try {
|
||||
const response = await putApi(`project/${projectId}/blockProject`);
|
||||
const data = response.data;
|
||||
|
||||
try{
|
||||
const response = await putApi(`project/${projectId}/blockProject`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(blockProjectSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(blockProjectError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(blockProjectSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(blockProjectError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Renew Alert Limit
|
||||
export const renewAlertLimitRequest = () => {
|
||||
return {
|
||||
type: types.ALERT_LIMIT_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ALERT_LIMIT_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const renewAlertLimitReset = () => {
|
||||
return {
|
||||
type: types.ALERT_LIMIT_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ALERT_LIMIT_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const renewAlertLimitSuccess = project => {
|
||||
return {
|
||||
type: types.ALERT_LIMIT_SUCCESS,
|
||||
payload: project
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ALERT_LIMIT_SUCCESS,
|
||||
payload: project,
|
||||
};
|
||||
};
|
||||
|
||||
export const renewAlertLimitError = error => {
|
||||
return {
|
||||
type: types.ALERT_LIMIT_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ALERT_LIMIT_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to block a project
|
||||
export const renewAlertLimit = (projectId,alertLimit) => async (dispatch) => {
|
||||
export const renewAlertLimit = (projectId, alertLimit) => async dispatch => {
|
||||
dispatch(renewAlertLimitRequest());
|
||||
|
||||
dispatch(renewAlertLimitRequest());
|
||||
try {
|
||||
const response = await putApi(`project/${projectId}/renewAlertLimit`, {
|
||||
alertLimit,
|
||||
});
|
||||
const data = response.data;
|
||||
|
||||
try{
|
||||
const response = await putApi(`project/${projectId}/renewAlertLimit`,{alertLimit});
|
||||
const data = response.data;
|
||||
|
||||
dispatch(renewAlertLimitSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(renewAlertLimitError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(renewAlertLimitSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(renewAlertLimitError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Restore project
|
||||
export const restoreProjectRequest = () => {
|
||||
return {
|
||||
type: types.RESTORE_PROJECT_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.RESTORE_PROJECT_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const restoreProjectReset = () => {
|
||||
return {
|
||||
type: types.RESTORE_PROJECT_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.RESTORE_PROJECT_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const restoreProjectSuccess = project => {
|
||||
return {
|
||||
type: types.RESTORE_PROJECT_SUCCESS,
|
||||
payload: project
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.RESTORE_PROJECT_SUCCESS,
|
||||
payload: project,
|
||||
};
|
||||
};
|
||||
|
||||
export const restoreProjectError = error => {
|
||||
return {
|
||||
type: types.RESTORE_PROJECT_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.RESTORE_PROJECT_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to restore a project
|
||||
export const restoreProject = projectId => async (dispatch) => {
|
||||
export const restoreProject = projectId => async dispatch => {
|
||||
dispatch(restoreProjectRequest());
|
||||
|
||||
dispatch(restoreProjectRequest());
|
||||
try {
|
||||
const response = await putApi(`project/${projectId}/restoreProject`);
|
||||
const data = response.data;
|
||||
|
||||
try{
|
||||
const response = await putApi(`project/${projectId}/restoreProject`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(restoreProjectSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(restoreProjectError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(restoreProjectSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(restoreProjectError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Unblock project
|
||||
export const unblockProjectRequest = () => {
|
||||
return {
|
||||
type: types.UNBLOCK_PROJECT_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UNBLOCK_PROJECT_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const unblockProjectReset = () => {
|
||||
return {
|
||||
type: types.UNBLOCK_PROJECT_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UNBLOCK_PROJECT_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const unblockProjectSuccess = (project) => {
|
||||
return {
|
||||
type: types.UNBLOCK_PROJECT_SUCCESS,
|
||||
payload: project
|
||||
};
|
||||
}
|
||||
export const unblockProjectSuccess = project => {
|
||||
return {
|
||||
type: types.UNBLOCK_PROJECT_SUCCESS,
|
||||
payload: project,
|
||||
};
|
||||
};
|
||||
|
||||
export const unblockProjectError = (error) => {
|
||||
return {
|
||||
type: types.UNBLOCK_PROJECT_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
export const unblockProjectError = error => {
|
||||
return {
|
||||
type: types.UNBLOCK_PROJECT_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to un-block a project
|
||||
export const unblockProject = projectId => async (dispatch) => {
|
||||
export const unblockProject = projectId => async dispatch => {
|
||||
dispatch(unblockProjectRequest());
|
||||
|
||||
dispatch(unblockProjectRequest());
|
||||
try {
|
||||
const response = await putApi(`project/${projectId}/unblockProject`);
|
||||
const data = response.data;
|
||||
|
||||
try{
|
||||
const response = await putApi(`project/${projectId}/unblockProject`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(unblockProjectSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(unblockProjectError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(unblockProjectSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(unblockProjectError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Add Project Notes
|
||||
export const addProjectNoteRequest = () => {
|
||||
return {
|
||||
type: types.ADD_PROJECT_NOTE_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_PROJECT_NOTE_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const addProjectNoteReset = () => {
|
||||
return {
|
||||
type: types.ADD_PROJECT_NOTE_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_PROJECT_NOTE_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const addProjectNoteSuccess = projectNote => {
|
||||
return {
|
||||
type: types.ADD_PROJECT_NOTE_SUCCESS,
|
||||
payload: projectNote
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_PROJECT_NOTE_SUCCESS,
|
||||
payload: projectNote,
|
||||
};
|
||||
};
|
||||
|
||||
export const addProjectNoteError = error => {
|
||||
return {
|
||||
type: types.ADD_PROJECT_NOTE_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_PROJECT_NOTE_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to add Admin Note
|
||||
export const addProjectNote = (projectId, values) => async (dispatch) => {
|
||||
export const addProjectNote = (projectId, values) => async dispatch => {
|
||||
dispatch(addProjectNoteRequest());
|
||||
|
||||
dispatch(addProjectNoteRequest());
|
||||
try {
|
||||
const response = await postApi(`project/${projectId}/addNote`, values);
|
||||
const data = response.data;
|
||||
|
||||
try{
|
||||
const response = await postApi(`project/${projectId}/addNote`, values);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(addProjectNoteSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(addProjectNoteError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(addProjectNoteSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(addProjectNoteError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Search Projects
|
||||
export const searchProjectsRequest = () => {
|
||||
return {
|
||||
type: types.SEARCH_PROJECTS_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SEARCH_PROJECTS_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchProjectsReset = () => {
|
||||
return {
|
||||
type: types.SEARCH_PROJECTS_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SEARCH_PROJECTS_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchProjectsSuccess = projects => {
|
||||
return {
|
||||
type: types.SEARCH_PROJECTS_SUCCESS,
|
||||
payload: projects
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SEARCH_PROJECTS_SUCCESS,
|
||||
payload: projects,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchProjectsError = error => {
|
||||
return {
|
||||
type: types.SEARCH_PROJECTS_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SEARCH_PROJECTS_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the search projects api
|
||||
export const searchProjects = (filter, skip, limit) => async (dispatch) => {
|
||||
const values = {
|
||||
filter
|
||||
};
|
||||
export const searchProjects = (filter, skip, limit) => async dispatch => {
|
||||
const values = {
|
||||
filter,
|
||||
};
|
||||
|
||||
dispatch(searchProjectsRequest());
|
||||
dispatch(searchProjectsRequest());
|
||||
|
||||
try{
|
||||
const response = await postApi(`project/projects/search?skip=${skip}&limit=${limit}`, values);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await postApi(
|
||||
`project/projects/search?skip=${skip}&limit=${limit}`,
|
||||
values
|
||||
);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(searchProjectsSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(searchProjectsError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(searchProjectsSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(searchProjectsError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,499 +1,497 @@
|
||||
import { getApi, putApi, deleteApi, postApi } from '../api';
|
||||
import * as types from '../constants/user';
|
||||
import errors from '../errors'
|
||||
import errors from '../errors';
|
||||
|
||||
export const fetchUsersRequest = () => {
|
||||
return {
|
||||
type: types.FETCH_USERS_REQUEST
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USERS_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchUsersSuccess = users => {
|
||||
return {
|
||||
type: types.FETCH_USERS_SUCCESS,
|
||||
payload: users
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USERS_SUCCESS,
|
||||
payload: users,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchUsersError = error => {
|
||||
return {
|
||||
type: types.FETCH_USERS_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USERS_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to fetch all users.
|
||||
export const fetchUsers = (skip, limit) => async (dispatch) => {
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
dispatch(fetchUsersRequest());
|
||||
export const fetchUsers = (skip, limit) => async dispatch => {
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
dispatch(fetchUsersRequest());
|
||||
|
||||
try{
|
||||
const response = await getApi(`user/users?skip=${skip}&limit=${limit}`);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await getApi(`user/users?skip=${skip}&limit=${limit}`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(fetchUsersSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchUsersError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(fetchUsersSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchUsersError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchUserRequest = () => {
|
||||
return {
|
||||
type: types.FETCH_USER_REQUEST
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USER_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchUserSuccess = user => {
|
||||
return {
|
||||
type: types.FETCH_USER_SUCCESS,
|
||||
payload: user
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USER_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchUserError = error => {
|
||||
return {
|
||||
type: types.FETCH_USER_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.FETCH_USER_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to fetch a user.
|
||||
export const fetchUser = userId => async (dispatch) => {
|
||||
dispatch(fetchUserRequest());
|
||||
|
||||
try{
|
||||
const response = await getApi(`user/users/${userId}`);
|
||||
const data = response.data;
|
||||
export const fetchUser = userId => async dispatch => {
|
||||
dispatch(fetchUserRequest());
|
||||
|
||||
dispatch(fetchUserSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchUserError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await getApi(`user/users/${userId}`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(fetchUserSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(fetchUserError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Update user setting
|
||||
|
||||
export const updateUserSettingRequest = () => {
|
||||
return {
|
||||
type: types.UPDATE_USER_SETTING_REQUEST
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UPDATE_USER_SETTING_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const updateUserSettingSuccess = userSetting => {
|
||||
return {
|
||||
type: types.UPDATE_USER_SETTING_SUCCESS,
|
||||
payload: userSetting
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UPDATE_USER_SETTING_SUCCESS,
|
||||
payload: userSetting,
|
||||
};
|
||||
};
|
||||
|
||||
export const updateUserSettingError = error => {
|
||||
return {
|
||||
type: types.UPDATE_USER_SETTING_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UPDATE_USER_SETTING_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to update user setting.
|
||||
export const updateUserSetting = values => async (dispatch) => {
|
||||
const data = new FormData();
|
||||
if (values.profilePic && values.profilePic[0]) {
|
||||
data.append('profilePic', values.profilePic[0], values.profilePic[0].name);
|
||||
}
|
||||
export const updateUserSetting = values => async dispatch => {
|
||||
const data = new FormData();
|
||||
if (values.profilePic && values.profilePic[0]) {
|
||||
data.append(
|
||||
'profilePic',
|
||||
values.profilePic[0],
|
||||
values.profilePic[0].name
|
||||
);
|
||||
}
|
||||
|
||||
data.append('name', values.name);
|
||||
data.append('email', values.email);
|
||||
data.append('companyPhoneNumber', values.companyPhoneNumber);
|
||||
data.append('timezone', values.timezone);
|
||||
dispatch(updateUserSettingRequest());
|
||||
data.append('name', values.name);
|
||||
data.append('email', values.email);
|
||||
data.append('companyPhoneNumber', values.companyPhoneNumber);
|
||||
data.append('timezone', values.timezone);
|
||||
dispatch(updateUserSettingRequest());
|
||||
|
||||
try{
|
||||
const response = await putApi(`user/profile/${values._id}`, data);
|
||||
const user = response.data;
|
||||
try {
|
||||
const response = await putApi(`user/profile/${values._id}`, data);
|
||||
const user = response.data;
|
||||
|
||||
dispatch(updateUserSettingSuccess(user));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(updateUserSettingError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(updateUserSettingSuccess(user));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(updateUserSettingError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
export const logFile = file => {
|
||||
return function (dispatch) {
|
||||
dispatch({type: 'LOG_FILE', payload: file});
|
||||
};
|
||||
}
|
||||
return function(dispatch) {
|
||||
dispatch({ type: 'LOG_FILE', payload: file });
|
||||
};
|
||||
};
|
||||
|
||||
export const resetFile = () => {
|
||||
return function (dispatch) {
|
||||
dispatch({type: 'RESET_FILE'});
|
||||
};
|
||||
}
|
||||
return function(dispatch) {
|
||||
dispatch({ type: 'RESET_FILE' });
|
||||
};
|
||||
};
|
||||
|
||||
//Delete user
|
||||
export const deleteUserRequest = () => {
|
||||
return {
|
||||
type: types.DELETE_USER_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_USER_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteUserReset = () => {
|
||||
return {
|
||||
type: types.DELETE_USER_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_USER_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteUserSuccess = user => {
|
||||
return {
|
||||
type: types.DELETE_USER_SUCCESS,
|
||||
payload: user
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_USER_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteUserError = error => {
|
||||
return {
|
||||
type: types.DELETE_USER_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.DELETE_USER_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to delete a user.
|
||||
export const deleteUser = userId => async (dispatch) => {
|
||||
dispatch(deleteUserRequest());
|
||||
export const deleteUser = userId => async dispatch => {
|
||||
dispatch(deleteUserRequest());
|
||||
|
||||
try{
|
||||
const response = await deleteApi(`user/${userId}`);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await deleteApi(`user/${userId}`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(deleteUserSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(deleteUserError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(deleteUserSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(deleteUserError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Restore user
|
||||
export const restoreUserRequest = () => {
|
||||
return {
|
||||
type: types.RESTORE_USER_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.RESTORE_USER_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const restoreUserReset = () => {
|
||||
return {
|
||||
type: types.RESTORE_USER_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.RESTORE_USER_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const restoreUserSuccess = user => {
|
||||
return {
|
||||
type: types.RESTORE_USER_SUCCESS,
|
||||
payload: user
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.RESTORE_USER_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
};
|
||||
|
||||
export const restoreUserError = error => {
|
||||
return {
|
||||
type: types.RESTORE_USER_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.RESTORE_USER_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to restore a user
|
||||
export const restoreUser = userId => async (dispatch) => {
|
||||
dispatch(restoreUserRequest());
|
||||
export const restoreUser = userId => async dispatch => {
|
||||
dispatch(restoreUserRequest());
|
||||
|
||||
try{
|
||||
const response = await putApi(`user/${userId}/restoreUser`);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await putApi(`user/${userId}/restoreUser`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(restoreUserSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(restoreUserError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(restoreUserSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(restoreUserError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Block user
|
||||
export const blockUserRequest = () => {
|
||||
return {
|
||||
type: types.BLOCK_USER_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.BLOCK_USER_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const blockUserReset = () => {
|
||||
return {
|
||||
type: types.BLOCK_USER_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.BLOCK_USER_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const blockUserSuccess = user => {
|
||||
return {
|
||||
type: types.BLOCK_USER_SUCCESS,
|
||||
payload: user
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.BLOCK_USER_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
};
|
||||
|
||||
export const blockUserError = error => {
|
||||
return {
|
||||
type: types.BLOCK_USER_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.BLOCK_USER_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to restore a user
|
||||
export const blockUser = userId => async (dispatch) => {
|
||||
dispatch(blockUserRequest());
|
||||
export const blockUser = userId => async dispatch => {
|
||||
dispatch(blockUserRequest());
|
||||
|
||||
try{
|
||||
const response = await putApi(`user/${userId}/blockUser`);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await putApi(`user/${userId}/blockUser`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(blockUserSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(blockUserError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(blockUserSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(blockUserError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Unblock user
|
||||
export const unblockUserRequest = () => {
|
||||
return {
|
||||
type: types.UNBLOCK_USER_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UNBLOCK_USER_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const unblockUserReset = () => {
|
||||
return {
|
||||
type: types.UNBLOCK_USER_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UNBLOCK_USER_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const unblockUserSuccess = user => {
|
||||
return {
|
||||
type: types.UNBLOCK_USER_SUCCESS,
|
||||
payload: user
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UNBLOCK_USER_SUCCESS,
|
||||
payload: user,
|
||||
};
|
||||
};
|
||||
|
||||
export const unblockUserError = error => {
|
||||
return {
|
||||
type: types.UNBLOCK_USER_FAILED,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.UNBLOCK_USER_FAILED,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to unblock a user
|
||||
export const unblockUser = userId => async (dispatch) => {
|
||||
dispatch(unblockUserRequest());
|
||||
export const unblockUser = userId => async dispatch => {
|
||||
dispatch(unblockUserRequest());
|
||||
|
||||
try{
|
||||
const response = await putApi(`user/${userId}/unblockUser`);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await putApi(`user/${userId}/unblockUser`);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(unblockUserSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(unblockUserError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(unblockUserSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(unblockUserError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Add Project Notes
|
||||
export const addUserNoteRequest = () => {
|
||||
return {
|
||||
type: types.ADD_USER_NOTE_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_USER_NOTE_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const addUserNoteReset = () => {
|
||||
return {
|
||||
type: types.ADD_USER_NOTE_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_USER_NOTE_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const addUserNoteSuccess = userNote => {
|
||||
return {
|
||||
type: types.ADD_USER_NOTE_SUCCESS,
|
||||
payload: userNote
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_USER_NOTE_SUCCESS,
|
||||
payload: userNote,
|
||||
};
|
||||
};
|
||||
|
||||
export const addUserNoteError = error => {
|
||||
return {
|
||||
type: types.ADD_USER_NOTE_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.ADD_USER_NOTE_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the API to add Admin Note
|
||||
export const addUserNote = (userId, values) => async (dispatch) => {
|
||||
dispatch(addUserNoteRequest());
|
||||
export const addUserNote = (userId, values) => async dispatch => {
|
||||
dispatch(addUserNoteRequest());
|
||||
|
||||
try{
|
||||
const response = await postApi(`user/${userId}/addNote`, values);
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await postApi(`user/${userId}/addNote`, values);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(addUserNoteSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(addUserNoteError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
dispatch(addUserNoteSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(addUserNoteError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
//Search Users
|
||||
export const searchUsersRequest = () => {
|
||||
return {
|
||||
type: types.SEARCH_USERS_REQUEST,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SEARCH_USERS_REQUEST,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchUsersReset = () => {
|
||||
return {
|
||||
type: types.SEARCH_USERS_RESET,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SEARCH_USERS_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchUsersSuccess = users => {
|
||||
return {
|
||||
type: types.SEARCH_USERS_SUCCESS,
|
||||
payload: users
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SEARCH_USERS_SUCCESS,
|
||||
payload: users,
|
||||
};
|
||||
};
|
||||
|
||||
export const searchUsersError = error => {
|
||||
return {
|
||||
type: types.SEARCH_USERS_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: types.SEARCH_USERS_FAILURE,
|
||||
payload: error,
|
||||
};
|
||||
};
|
||||
|
||||
// Calls the search users api
|
||||
export const searchUsers = (filter, skip, limit) => async (dispatch) => {
|
||||
const values = {
|
||||
filter
|
||||
};
|
||||
skip = skip ? parseInt(skip) : 0
|
||||
limit = limit ? parseInt(limit) : 10
|
||||
|
||||
dispatch(searchUsersRequest());
|
||||
export const searchUsers = (filter, skip, limit) => async dispatch => {
|
||||
const values = {
|
||||
filter,
|
||||
};
|
||||
skip = skip ? parseInt(skip) : 0;
|
||||
limit = limit ? parseInt(limit) : 10;
|
||||
|
||||
try{
|
||||
const response = await postApi(`user/users/search?skip=${skip}&limit=${limit}`, values);
|
||||
const data = response.data;
|
||||
dispatch(searchUsersRequest());
|
||||
|
||||
dispatch(searchUsersSuccess(data));
|
||||
return response;
|
||||
}catch(error){
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if(error && error.message){
|
||||
errorMsg = error.message;
|
||||
}
|
||||
else{
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(searchUsersError(errors(errorMsg)));
|
||||
}
|
||||
}
|
||||
try {
|
||||
const response = await postApi(
|
||||
`user/users/search?skip=${skip}&limit=${limit}`,
|
||||
values
|
||||
);
|
||||
const data = response.data;
|
||||
|
||||
dispatch(searchUsersSuccess(data));
|
||||
return response;
|
||||
} catch (error) {
|
||||
let errorMsg;
|
||||
if (error && error.response && error.response.data)
|
||||
errorMsg = error.response.data;
|
||||
if (error && error.data) {
|
||||
errorMsg = error.data;
|
||||
}
|
||||
if (error && error.message) {
|
||||
errorMsg = error.message;
|
||||
} else {
|
||||
errorMsg = 'Network Error';
|
||||
}
|
||||
dispatch(searchUsersError(errors(errorMsg)));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import axios from 'axios';
|
||||
import {
|
||||
API_URL
|
||||
} from './config';
|
||||
import {
|
||||
User
|
||||
} from './config';
|
||||
import { API_URL } from './config';
|
||||
import { User } from './config';
|
||||
import { history } from './store';
|
||||
const baseURL = API_URL;
|
||||
|
||||
@@ -12,27 +8,25 @@ const Q = require('q');
|
||||
|
||||
const headers = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
};
|
||||
|
||||
|
||||
|
||||
export function postApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken();
|
||||
const deffered = Q.defer();
|
||||
|
||||
axios({
|
||||
method: 'POST',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
data,
|
||||
})
|
||||
.then(function (response) {
|
||||
.then(function(response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch(function(error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
@@ -49,17 +43,17 @@ export function postApi(url, data) {
|
||||
|
||||
export function getApi(url) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken();
|
||||
const deffered = Q.defer();
|
||||
axios({
|
||||
method: 'GET',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers
|
||||
headers,
|
||||
})
|
||||
.then(function (response) {
|
||||
.then(function(response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch(function(error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
@@ -75,21 +69,20 @@ export function getApi(url) {
|
||||
return deffered.promise;
|
||||
}
|
||||
|
||||
|
||||
export function putApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken();
|
||||
const deffered = Q.defer();
|
||||
axios({
|
||||
method: 'PUT',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
data,
|
||||
})
|
||||
.then(function (response) {
|
||||
.then(function(response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch(function(error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
@@ -107,18 +100,18 @@ export function putApi(url, data) {
|
||||
|
||||
export function deleteApi(url, data) {
|
||||
if (User.isLoggedIn())
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken()
|
||||
headers['Authorization'] = 'Basic ' + User.getAccessToken();
|
||||
const deffered = Q.defer();
|
||||
axios({
|
||||
method: 'DELETE',
|
||||
url: `${baseURL}/${url}`,
|
||||
headers,
|
||||
data
|
||||
data,
|
||||
})
|
||||
.then(function (response) {
|
||||
.then(function(response) {
|
||||
deffered.resolve(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch(function(error) {
|
||||
if (error && error.response && error.response.status === 401) {
|
||||
User.clear();
|
||||
history.push('/login');
|
||||
|
||||
@@ -1,35 +1,40 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
|
||||
class NotFound extends Component {
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
<div className="db-World-root" >
|
||||
|
||||
<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
|
||||
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'
|
||||
|
||||
NotFound.displayName = 'NotFound';
|
||||
|
||||
export default NotFound;
|
||||
|
||||
@@ -3,49 +3,59 @@ import Clipboard from 'clipboard';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
class ClipboardWrap extends React.Component {
|
||||
componentDidMount () {
|
||||
const button = this.button
|
||||
const input = this.input
|
||||
|
||||
this.clipboard = new Clipboard(
|
||||
button, {
|
||||
target: () => input
|
||||
}
|
||||
)
|
||||
componentDidMount() {
|
||||
const button = this.button;
|
||||
const input = this.input;
|
||||
|
||||
this.clipboard = new Clipboard(button, {
|
||||
target: () => input,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
componentWillUnmount() {
|
||||
this.clipboard.destroy()
|
||||
this.clipboard.destroy();
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
render() {
|
||||
const { value } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
ref={(element) => { this.input = element }}
|
||||
ref={element => {
|
||||
this.input = element;
|
||||
}}
|
||||
type={'text'}
|
||||
value={value}
|
||||
className="bs-TextInput"
|
||||
style={{ width: 360, borderTopRightRadius: 0, borderBottomRightRadius: 0 }}
|
||||
style={{
|
||||
width: 360,
|
||||
borderTopRightRadius: 0,
|
||||
borderBottomRightRadius: 0,
|
||||
}}
|
||||
readOnly
|
||||
/>
|
||||
<button
|
||||
ref={(element) => { this.button = element }}
|
||||
ref={element => {
|
||||
this.button = element;
|
||||
}}
|
||||
className="bs-Button bs-Button--blue"
|
||||
style={{ borderTopLeftRadius: 0, borderBottomLeftRadius: 0 }}
|
||||
>Copy
|
||||
style={{
|
||||
borderTopLeftRadius: 0,
|
||||
borderBottomLeftRadius: 0,
|
||||
}}
|
||||
>
|
||||
Copy
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ClipboardWrap.displayName = 'ClipboardWrap';
|
||||
|
||||
ClipboardWrap.propTypes = {
|
||||
value: PropTypes.string
|
||||
}
|
||||
value: PropTypes.string,
|
||||
};
|
||||
|
||||
export default ClipboardWrap
|
||||
export default ClipboardWrap;
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function (Cm){
|
||||
return (props) => (
|
||||
<div className="bs-BIM">
|
||||
<div
|
||||
className="ContextualLayer-layer--topleft ContextualLayer-layer--anytop ContextualLayer-layer--anyleft ContextualLayer-context--topleft ContextualLayer-context--anytop ContextualLayer-context--anyleft ContextualLayer-container ContextualLayer--pointerEvents"
|
||||
>
|
||||
<Cm {...props} />
|
||||
export default function(Cm) {
|
||||
return props =>
|
||||
((
|
||||
<div className="bs-BIM">
|
||||
<div className="ContextualLayer-layer--topleft ContextualLayer-layer--anytop ContextualLayer-layer--anyleft ContextualLayer-context--topleft ContextualLayer-context--anytop ContextualLayer-context--anyleft ContextualLayer-container ContextualLayer--pointerEvents">
|
||||
<Cm {...props} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
).displayName = 'ContextModal'
|
||||
).displayName = 'ContextModal');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import SideNav from './nav/SideNav';
|
||||
import TopNav from './nav/TopNav';
|
||||
import { withRouter } from 'react-router';
|
||||
import ShouldRender from './basic/ShouldRender';
|
||||
import ProfileMenu from './profile/ProfileMenu';
|
||||
import ProfileMenu from './profile/ProfileMenu';
|
||||
import ClickOutside from 'react-click-outside';
|
||||
import { hideProfileMenu } from '../actions/profile';
|
||||
import NotificationMenu from './notification/NotificationMenu';
|
||||
@@ -14,10 +14,14 @@ import { closeNotificationMenu } from '../actions/notification';
|
||||
import { fetchUsers } from '../actions/user';
|
||||
|
||||
export class DashboardApp extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
const { fetchUsers, ready, user } = this.props;
|
||||
if (user.users && user.users.users && user.users.users.length === 0 && !user.users.requesting){
|
||||
if (
|
||||
user.users &&
|
||||
user.users.users &&
|
||||
user.users.users.length === 0 &&
|
||||
!user.users.requesting
|
||||
) {
|
||||
fetchUsers().then(() => ready && ready());
|
||||
} else {
|
||||
this.props.ready && this.props.ready();
|
||||
@@ -26,90 +30,123 @@ export class DashboardApp extends Component {
|
||||
|
||||
showProjectForm = () => {
|
||||
this.props.showForm();
|
||||
if(window.location.href.indexOf('localhost') <= -1){
|
||||
if (window.location.href.indexOf('localhost') <= -1) {
|
||||
this.context.mixpanel.track('Project Form Opened');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
hideProfileMenu = () => {
|
||||
this.props.hideProfileMenu();
|
||||
if(window.location.href.indexOf('localhost') <= -1){
|
||||
if (window.location.href.indexOf('localhost') <= -1) {
|
||||
this.context.mixpanel.track('Profile Menu Closed');
|
||||
}
|
||||
}
|
||||
};
|
||||
closeNotificationMenu = () => {
|
||||
this.props.closeNotificationMenu();
|
||||
if(window.location.href.indexOf('localhost') <= -1){
|
||||
if (window.location.href.indexOf('localhost') <= -1) {
|
||||
this.context.mixpanel.track('Notification Menu Closed');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleKeyBoard = e => {
|
||||
switch (e.key) {
|
||||
case 'Escape':
|
||||
this.props.closeNotificationMenu();
|
||||
this.props.hideProfileMenu();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
handleKeyBoard = (e) => {
|
||||
switch(e.key){
|
||||
case 'Escape':
|
||||
this.props.closeNotificationMenu();
|
||||
this.props.hideProfileMenu();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { user, children } = this.props
|
||||
const { user, children } = this.props;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
<ClickOutside onClickOutside={this.hideProfileMenu}>
|
||||
<ProfileMenu visible={this.props.profile.menuVisible} />
|
||||
</ClickOutside>
|
||||
<ClickOutside onClickOutside={this.closeNotificationMenu}>
|
||||
<NotificationMenu visible={this.props.notification.notificationsVisible} />
|
||||
<NotificationMenu
|
||||
visible={this.props.notification.notificationsVisible}
|
||||
/>
|
||||
</ClickOutside>
|
||||
|
||||
<div onKeyDown={this.handleKeyBoard} className="db-World-root" >
|
||||
|
||||
<ShouldRender if={!user.users.requesting && user.users.success}>
|
||||
<div onKeyDown={this.handleKeyBoard} className="db-World-root">
|
||||
<ShouldRender
|
||||
if={!user.users.requesting && user.users.success}
|
||||
>
|
||||
<div className="db-World-wrapper Box-root Flex-flex Flex-direction--column">
|
||||
|
||||
<SideNav />
|
||||
|
||||
<div className="db-World-mainPane Box-root Padding-right--20" >
|
||||
|
||||
<div className="db-World-mainPane Box-root Padding-right--20">
|
||||
{children}
|
||||
|
||||
</div>
|
||||
|
||||
<TopNav />
|
||||
|
||||
</div>
|
||||
</ShouldRender>
|
||||
|
||||
<ShouldRender if={user.users.requesting}>
|
||||
<div id="app-loading" style={{ 'position': 'fixed', 'top': '0', 'bottom': '0', 'left': '0', 'right': '0', 'zIndex': '999', 'display': 'flex', 'justifyContent': 'center', 'alignItems': 'center' }}>
|
||||
<div style={{ 'transform': 'scale(2)' }}>
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" className="bs-Spinner-svg">
|
||||
<ellipse cx="12" cy="12" rx="10" ry="10" className="bs-Spinner-ellipse"></ellipse>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
id="app-loading"
|
||||
style={{
|
||||
position: 'fixed',
|
||||
top: '0',
|
||||
bottom: '0',
|
||||
left: '0',
|
||||
right: '0',
|
||||
zIndex: '999',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<div style={{ transform: 'scale(2)' }}>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="bs-Spinner-svg"
|
||||
>
|
||||
<ellipse
|
||||
cx="12"
|
||||
cy="12"
|
||||
rx="10"
|
||||
ry="10"
|
||||
className="bs-Spinner-ellipse"
|
||||
></ellipse>
|
||||
</svg>
|
||||
</div>
|
||||
</ShouldRender>
|
||||
|
||||
<ShouldRender if={user.users.error}>
|
||||
<div id="app-loading" style={{ 'backgroundColor':'#E6EBF1', 'position': 'fixed', 'top': '0', 'bottom': '0', 'left': '0', 'right': '0', 'zIndex': '999', 'display': 'flex', 'justifyContent': 'center', 'alignItems': 'center' }}>
|
||||
<div>Cannot connect to server.</div>
|
||||
</div>
|
||||
</ShouldRender>
|
||||
</div>
|
||||
</ShouldRender>
|
||||
|
||||
<ShouldRender if={user.users.error}>
|
||||
<div
|
||||
id="app-loading"
|
||||
style={{
|
||||
backgroundColor: '#E6EBF1',
|
||||
position: 'fixed',
|
||||
top: '0',
|
||||
bottom: '0',
|
||||
left: '0',
|
||||
right: '0',
|
||||
zIndex: '999',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<div>Cannot connect to server.</div>
|
||||
</div>
|
||||
</ShouldRender>
|
||||
</div>
|
||||
|
||||
</Fragment>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DashboardApp.displayName = 'DashboardApp'
|
||||
DashboardApp.displayName = 'DashboardApp';
|
||||
|
||||
DashboardApp.propTypes = {
|
||||
profile: PropTypes.object.isRequired,
|
||||
@@ -120,25 +157,29 @@ DashboardApp.propTypes = {
|
||||
fetchUsers: PropTypes.func,
|
||||
children: PropTypes.any,
|
||||
ready: PropTypes.func,
|
||||
user: PropTypes.object.isRequired
|
||||
}
|
||||
user: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
profile: state.profileSettings,
|
||||
notification: state.notifications,
|
||||
user: state.user
|
||||
})
|
||||
user: state.user,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => (
|
||||
bindActionCreators({
|
||||
hideProfileMenu,
|
||||
closeNotificationMenu,
|
||||
fetchUsers
|
||||
}, dispatch)
|
||||
)
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators(
|
||||
{
|
||||
hideProfileMenu,
|
||||
closeNotificationMenu,
|
||||
fetchUsers,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
|
||||
DashboardApp.contextTypes = {
|
||||
mixpanel: PropTypes.object.isRequired
|
||||
mixpanel: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(DashboardApp));
|
||||
export default withRouter(
|
||||
connect(mapStateToProps, mapDispatchToProps)(DashboardApp)
|
||||
);
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import React from 'react';
|
||||
|
||||
function DataPathHoC(WrappedComponent, data) {
|
||||
return class extends React.Component {
|
||||
static displayName = 'HocCom';
|
||||
render() {
|
||||
// Wraps the input component in a container, without mutating it. Good!
|
||||
return <WrappedComponent {...this.props} webhook={data} data={data} />;
|
||||
}
|
||||
}
|
||||
return class extends React.Component {
|
||||
static displayName = 'HocCom';
|
||||
render() {
|
||||
// Wraps the input component in a container, without mutating it. Good!
|
||||
return (
|
||||
<WrappedComponent {...this.props} webhook={data} data={data} />
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
DataPathHoC.displayName = 'DataPathHoC';
|
||||
|
||||
export default DataPathHoC
|
||||
export default DataPathHoC;
|
||||
|
||||
@@ -1,43 +1,49 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const composableComponent = (ComposedComponent) => {
|
||||
const composableComponent = ComposedComponent => {
|
||||
class Modal extends Component {
|
||||
constructor(props){
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.onClose = this.onClose.bind(this);
|
||||
this.onConfirm = this.onConfirm.bind(this);
|
||||
}
|
||||
onClose =(value)=> {
|
||||
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)=> {
|
||||
};
|
||||
onConfirm = value => {
|
||||
const _this = this;
|
||||
if (this.props.item.onConfirm) {
|
||||
this.props.item.onConfirm(value)
|
||||
.then(() => _this.props.onClose(_this.props.item),
|
||||
()=> {})
|
||||
this.props.item.onConfirm(value).then(
|
||||
() => _this.props.onClose(_this.props.item),
|
||||
() => {}
|
||||
);
|
||||
} else {
|
||||
this.props.onClose(this.props.item)
|
||||
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'};
|
||||
const modalContainerStyle = {
|
||||
overflowX: 'auto',
|
||||
overflowY: 'scroll',
|
||||
display: 'block',
|
||||
top: '0px',
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={mainClass}
|
||||
style={{
|
||||
zIndex: (zIndex + 1) * 10000
|
||||
zIndex: (zIndex + 1) * 10000,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
@@ -47,12 +53,17 @@ const composableComponent = (ComposedComponent) => {
|
||||
opacity: 1,
|
||||
transform: 'none',
|
||||
display: 'block',
|
||||
pointerEvents: 'auto'
|
||||
pointerEvents: 'auto',
|
||||
}}
|
||||
>
|
||||
|
||||
<div className="modal_container" style={modalContainerStyle}>
|
||||
<ComposedComponent closeThisDialog={this.onClose} confirmThisDialog={this.onConfirm} />
|
||||
<div
|
||||
className="modal_container"
|
||||
style={modalContainerStyle}
|
||||
>
|
||||
<ComposedComponent
|
||||
closeThisDialog={this.onClose}
|
||||
confirmThisDialog={this.onConfirm}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,15 +73,14 @@ const composableComponent = (ComposedComponent) => {
|
||||
Modal.propTypes = {
|
||||
onConfirm: PropTypes.func,
|
||||
item: PropTypes.object.isRequired,
|
||||
onClose:PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
extraClasses: PropTypes.string,
|
||||
zIndex: PropTypes.number.isRequired
|
||||
}
|
||||
zIndex: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
Modal.displayName = 'Modal'
|
||||
Modal.displayName = 'Modal';
|
||||
|
||||
return Modal;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default composableComponent;
|
||||
export default composableComponent;
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
/**
|
||||
* @function Modalize
|
||||
* @param {React.Props} props Props comprise an object with 3 JSX values for `HEADER`, `CONTENT` & `FOOTER`
|
||||
* @returns {JSX.Element} A modal and a child component.
|
||||
*/
|
||||
*/
|
||||
export function Modalize({ HEADER, CONTENT, FOOTER }) {
|
||||
|
||||
return HEADER && CONTENT && FOOTER ? (
|
||||
|
||||
<div className="ModalLayer-wash Box-root Flex-flex Flex-alignItems--flexStart Flex-justifyContent--center">
|
||||
|
||||
<div className="ModalLayer-contents" tabIndex="-1" style={{marginTop: 105}}>
|
||||
|
||||
<div
|
||||
className="ModalLayer-contents"
|
||||
tabIndex="-1"
|
||||
style={{ marginTop: 105 }}
|
||||
>
|
||||
<div className="bs-BIM">
|
||||
|
||||
<form>
|
||||
<div className="bs-Modal bs-Modal--medium">
|
||||
|
||||
<div className="bs-Modal-header">
|
||||
<div className="bs-Modal-header-copy">
|
||||
{HEADER}
|
||||
@@ -27,38 +25,29 @@ export function Modalize({ HEADER, CONTENT, FOOTER }) {
|
||||
<div className="bs-Modal-messages"></div>
|
||||
</div>
|
||||
|
||||
<div className="bs-Modal-content">
|
||||
{CONTENT}
|
||||
</div>
|
||||
|
||||
<div className="bs-Modal-footer">
|
||||
{FOOTER}
|
||||
</div>
|
||||
<div className="bs-Modal-content">{CONTENT}</div>
|
||||
|
||||
<div className="bs-Modal-footer">{FOOTER}</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
) : null;
|
||||
) : null;
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
HEADER: state.modal.header,
|
||||
CONTENT: state.modal.content,
|
||||
FOOTER: state.modal.footer
|
||||
})
|
||||
FOOTER: state.modal.footer,
|
||||
});
|
||||
|
||||
Modalize.propTypes = {
|
||||
HEADER: PropTypes.string.isRequired,
|
||||
CONTENT: PropTypes.string.isRequired,
|
||||
FOOTER: PropTypes.string.isRequired
|
||||
}
|
||||
FOOTER: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
Modalize.displayName = 'Modalize'
|
||||
Modalize.displayName = 'Modalize';
|
||||
|
||||
export default connect(mapStateToProps)(Modalize);
|
||||
export default connect(mapStateToProps)(Modalize);
|
||||
|
||||
@@ -3,37 +3,37 @@ import { connect } from 'react-redux';
|
||||
import { User } from '../config';
|
||||
import { history } from '../store';
|
||||
|
||||
export default function (ComposedComponent) {
|
||||
class NotAuthentication extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
export default function(ComposedComponent) {
|
||||
class NotAuthentication extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
|
||||
this.isAuthenticated = User.isLoggedIn();
|
||||
this.isAuthenticated = User.isLoggedIn();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.isAuthenticated) {
|
||||
history.push('/project/project/monitoring');
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.isAuthenticated) {
|
||||
history.push('/project/project/monitoring');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return <ComposedComponent {...this.props} />;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.isAuthenticated) {
|
||||
history.push('/project/project/monitoring');
|
||||
}
|
||||
function mapStateToProps(state_Ignored) {
|
||||
return {};
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.isAuthenticated) {
|
||||
history.push('/project/project/monitoring');
|
||||
}
|
||||
}
|
||||
NotAuthentication.displayName = 'NotAuthentication';
|
||||
|
||||
render() {
|
||||
return <ComposedComponent {...this.props} />;
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state_Ignored) {
|
||||
return {};
|
||||
}
|
||||
|
||||
NotAuthentication.displayName = 'NotAuthentication'
|
||||
|
||||
return connect(mapStateToProps)(NotAuthentication);
|
||||
}
|
||||
return connect(mapStateToProps)(NotAuthentication);
|
||||
}
|
||||
|
||||
@@ -8,42 +8,46 @@ export default (ComposedComponent, extras) => {
|
||||
class OutsideCkick extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
||||
this.setWrapperRef = this.setWrapperRef.bind(this);
|
||||
this.handleClickOutside = this.handleClickOutside.bind(this);
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('mousedown', this.handleClickOutside);
|
||||
}
|
||||
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('mousedown', this.handleClickOutside);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the wrapper ref
|
||||
*/
|
||||
setWrapperRef(node) {
|
||||
this.wrapperRef = node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Alert if clicked on outside of element
|
||||
*/
|
||||
handleClickOutside =(event)=> {
|
||||
handleClickOutside = event => {
|
||||
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
|
||||
extras.closeModal();
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
return <div ref={this.setWrapperRef}> <ComposedComponent {...this.props} /> </div>
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div ref={this.setWrapperRef}>
|
||||
{' '}
|
||||
<ComposedComponent {...this.props} />{' '}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
OutsideCkick.displayName = 'PublicPage'
|
||||
|
||||
return OutsideCkick
|
||||
}
|
||||
OutsideCkick.displayName = 'PublicPage';
|
||||
|
||||
return OutsideCkick;
|
||||
};
|
||||
|
||||
@@ -5,21 +5,21 @@ import routes from '../routes';
|
||||
const { allRoutes } = routes;
|
||||
|
||||
const PublicPage = () => (
|
||||
<Switch>
|
||||
{allRoutes
|
||||
.filter(route => route.isPublic)
|
||||
.map((route, index) => (
|
||||
<Route
|
||||
component={route.component}
|
||||
exact={route.exact}
|
||||
path={route.path}
|
||||
key={index}
|
||||
/>
|
||||
))}
|
||||
<Redirect to='/login' />
|
||||
</Switch>
|
||||
<Switch>
|
||||
{allRoutes
|
||||
.filter(route => route.isPublic)
|
||||
.map((route, index) => (
|
||||
<Route
|
||||
component={route.component}
|
||||
exact={route.exact}
|
||||
path={route.path}
|
||||
key={index}
|
||||
/>
|
||||
))}
|
||||
<Redirect to="/login" />
|
||||
</Switch>
|
||||
);
|
||||
|
||||
PublicPage.displayName = 'PublicPage'
|
||||
PublicPage.displayName = 'PublicPage';
|
||||
|
||||
export default PublicPage;
|
||||
|
||||
@@ -4,50 +4,53 @@ import PropTypes from 'prop-types';
|
||||
import { User } from '../config';
|
||||
import { history } from '../store';
|
||||
|
||||
export default function (ComposedComponent) {
|
||||
class Authentication extends Component {
|
||||
export default function(ComposedComponent) {
|
||||
class Authentication extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props = props;
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.props = props;
|
||||
this.isAuthenticated = User.isLoggedIn();
|
||||
}
|
||||
|
||||
this.isAuthenticated = User.isLoggedIn();
|
||||
componentDidMount() {
|
||||
if (!this.isAuthenticated) {
|
||||
history.push('/login', {
|
||||
continue: this.props.location.pathname,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (!this.isAuthenticated) {
|
||||
history.push('/login', {
|
||||
continue: this.props.location.pathname,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
PropTypes = {
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
render() {
|
||||
return <ComposedComponent {...this.props} />;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.isAuthenticated) {
|
||||
history.push('/login', { continue: this.props.location.pathname });
|
||||
}
|
||||
Authentication.propTypes = {
|
||||
location: PropTypes.object,
|
||||
};
|
||||
|
||||
Authentication.displayName = 'RequireAuth';
|
||||
|
||||
function mapStateToProps(state_Ignored) {
|
||||
return {};
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (!this.isAuthenticated) {
|
||||
history.push('/login', { continue: this.props.location.pathname });
|
||||
}
|
||||
function mapDispatchToProps(dispatch_Ignored) {
|
||||
return {};
|
||||
}
|
||||
|
||||
PropTypes = {
|
||||
router: PropTypes.object
|
||||
}
|
||||
|
||||
render() {
|
||||
return <ComposedComponent {...this.props} />;
|
||||
}
|
||||
}
|
||||
|
||||
Authentication.propTypes = {
|
||||
location: PropTypes.object
|
||||
}
|
||||
|
||||
Authentication.displayName = 'RequireAuth'
|
||||
|
||||
function mapStateToProps(state_Ignored) {
|
||||
return {};
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch_Ignored) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return connect(mapStateToProps, mapDispatchToProps)(Authentication);
|
||||
return connect(mapStateToProps, mapDispatchToProps)(Authentication);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +1,48 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import ShouldRender from '../basic/ShouldRender';
|
||||
import { Field } from 'redux-form';
|
||||
|
||||
const AdminNote = ({ fields, meta: { error, submitFailed } }) => {
|
||||
|
||||
return (
|
||||
<ul>
|
||||
{
|
||||
fields.map((val, i) => {
|
||||
return (
|
||||
<li key={i}>
|
||||
<div className="bs-Fieldset-row">
|
||||
<label className="bs-Fieldset-label">Admin Note</label>
|
||||
<div className="bs-Fieldset-fields bs-Fieldset-fields--wide">
|
||||
<Field
|
||||
id={`txtAdminNote${i}`}
|
||||
rows="5"
|
||||
cols="100"
|
||||
className="bs-TextArea"
|
||||
type="text"
|
||||
name={`${val}.note`}
|
||||
component="textarea"
|
||||
/>
|
||||
</div>
|
||||
{fields.map((val, i) => {
|
||||
return (
|
||||
<li key={i}>
|
||||
<div className="bs-Fieldset-row">
|
||||
<label className="bs-Fieldset-label">
|
||||
Admin Note
|
||||
</label>
|
||||
<div className="bs-Fieldset-fields bs-Fieldset-fields--wide">
|
||||
<Field
|
||||
id={`txtAdminNote${i}`}
|
||||
rows="5"
|
||||
cols="100"
|
||||
className="bs-TextArea"
|
||||
type="text"
|
||||
name={`${val}.note`}
|
||||
component="textarea"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bs-Fieldset-row">
|
||||
<label className="bs-Fieldset-label"></label>
|
||||
<div className="bs-Fieldset-fields">
|
||||
<div className="Box-root Flex-flex Flex-alignItems--center">
|
||||
<button
|
||||
id={`btnRemoveAdminNote${i}`}
|
||||
className="bs-Button bs-DeprecatedButton"
|
||||
type="button"
|
||||
onClick={() => fields.remove(i)}
|
||||
>
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
<div className="bs-Fieldset-row">
|
||||
<label className="bs-Fieldset-label"></label>
|
||||
<div className="bs-Fieldset-fields">
|
||||
<div className="Box-root Flex-flex Flex-alignItems--center">
|
||||
<button
|
||||
id={`btnRemoveAdminNote${i}`}
|
||||
className="bs-Button bs-DeprecatedButton"
|
||||
type="button"
|
||||
onClick={() => fields.remove(i)}
|
||||
>
|
||||
Remove
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
|
||||
<li>
|
||||
<div className="bs-Fieldset-row">
|
||||
@@ -52,41 +50,34 @@ const AdminNote = ({ fields, meta: { error, submitFailed } }) => {
|
||||
<div className="bs-Fieldset-fields">
|
||||
<div className="Box-root Flex-flex Flex-alignItems--center">
|
||||
<div>
|
||||
|
||||
<button
|
||||
id="btnAddAdminNotes"
|
||||
type="button"
|
||||
className="bs-Button bs-FileUploadButton bs-Button--icon bs-Button--new"
|
||||
onClick={() => fields.push({note: ''})}
|
||||
>
|
||||
Add Notes
|
||||
</button>
|
||||
<ShouldRender if={submitFailed && error}>
|
||||
<span>{error}</span>
|
||||
</ShouldRender>
|
||||
|
||||
<button
|
||||
id="btnAddAdminNotes"
|
||||
type="button"
|
||||
className="bs-Button bs-FileUploadButton bs-Button--icon bs-Button--new"
|
||||
onClick={() => fields.push({ note: '' })}
|
||||
>
|
||||
Add Notes
|
||||
</button>
|
||||
<ShouldRender if={submitFailed && error}>
|
||||
<span>{error}</span>
|
||||
</ShouldRender>
|
||||
</div>
|
||||
</div>
|
||||
<p className="bs-Fieldset-explanation">
|
||||
<span>
|
||||
You can add any number of notes.
|
||||
</span>
|
||||
<span>You can add any number of notes.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
AdminNote.displayName = 'AdminNote'
|
||||
AdminNote.displayName = 'AdminNote';
|
||||
|
||||
AdminNote.propTypes = {
|
||||
meta: PropTypes.object.isRequired,
|
||||
fields: PropTypes.oneOfType([
|
||||
PropTypes.array,
|
||||
PropTypes.object
|
||||
]).isRequired,
|
||||
}
|
||||
fields: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired,
|
||||
};
|
||||
|
||||
export {AdminNote}
|
||||
export { AdminNote };
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import PropTypes from 'prop-types';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { FormLoader } from '../basic/Loader';
|
||||
@@ -15,18 +15,17 @@ function validate(values) {
|
||||
|
||||
if (values.adminNotes) {
|
||||
for (let i = 0; i < values.adminNotes.length; i++) {
|
||||
const adminNotesErrors = {}
|
||||
const adminNotesErrors = {};
|
||||
if (values.adminNotes[i] && values.adminNotes[i].note) {
|
||||
|
||||
if (!Validate.text(values.adminNotes[i].note)) {
|
||||
adminNotesErrors.note = 'Note is not in text format.'
|
||||
adminNotesArrayErrors[i] = adminNotesErrors
|
||||
adminNotesErrors.note = 'Note is not in text format.';
|
||||
adminNotesArrayErrors[i] = adminNotesErrors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (adminNotesArrayErrors.length) {
|
||||
errors.adminNotes = adminNotesArrayErrors
|
||||
errors.adminNotes = adminNotesArrayErrors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,13 +33,12 @@ function validate(values) {
|
||||
}
|
||||
|
||||
export class AdminNotes extends Component {
|
||||
|
||||
submitForm = async (values) => {
|
||||
submitForm = async values => {
|
||||
await this.props.addNote(this.props.id, values.adminNotes);
|
||||
if (window.location.href.indexOf('localhost') <= -1) {
|
||||
this.context.mixpanel.track('Admin Notes Updated', values);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { handleSubmit, requesting } = this.props;
|
||||
@@ -53,7 +51,9 @@ export class AdminNotes extends Component {
|
||||
<span className="Text-color--inherit Text-display--inline Text-fontSize--16 Text-fontWeight--medium Text-lineHeight--24 Text-typeface--base Text-wrap--wrap">
|
||||
<span>Admin Notes</span>
|
||||
</span>
|
||||
<p><span>Leave a comment.</span></p>
|
||||
<p>
|
||||
<span>Leave a comment.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<form onSubmit={handleSubmit(this.submitForm)}>
|
||||
@@ -62,9 +62,9 @@ export class AdminNotes extends Component {
|
||||
<div className="bs-Fieldset-wrapper Box-root Margin-bottom--2">
|
||||
<fieldset className="bs-Fieldset">
|
||||
<div className="bs-Fieldset-rows">
|
||||
<FieldArray
|
||||
name="adminNotes"
|
||||
component={ AdminNote }
|
||||
<FieldArray
|
||||
name="adminNotes"
|
||||
component={AdminNote}
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -72,50 +72,49 @@ export class AdminNotes extends Component {
|
||||
</div>
|
||||
</div>
|
||||
<div className="bs-ContentSection-footer bs-ContentSection-content Box-root Box-background--white Flex-flex Flex-alignItems--center Flex-justifyContent--spaceBetween Padding-horizontal--20 Padding-vertical--12">
|
||||
<span className="db-SettingsForm-footerMessage"></span>
|
||||
<div>
|
||||
<button
|
||||
className="bs-Button bs-DeprecatedButton bs-Button--blue"
|
||||
disabled={requesting}
|
||||
type="submit">
|
||||
<ShouldRender if={requesting}>
|
||||
<FormLoader />
|
||||
</ShouldRender>
|
||||
<ShouldRender if={!requesting}>
|
||||
<span>Save</span>
|
||||
</ShouldRender>
|
||||
</button>
|
||||
<span className="db-SettingsForm-footerMessage"></span>
|
||||
<div>
|
||||
<button
|
||||
className="bs-Button bs-DeprecatedButton bs-Button--blue"
|
||||
disabled={requesting}
|
||||
type="submit"
|
||||
>
|
||||
<ShouldRender if={requesting}>
|
||||
<FormLoader />
|
||||
</ShouldRender>
|
||||
<ShouldRender if={!requesting}>
|
||||
<span>Save</span>
|
||||
</ShouldRender>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AdminNotes.displayName = 'AdminNotes'
|
||||
AdminNotes.displayName = 'AdminNotes';
|
||||
|
||||
const mapDispatchToProps = dispatch => bindActionCreators(
|
||||
{ }
|
||||
, dispatch);
|
||||
const mapDispatchToProps = dispatch => bindActionCreators({}, dispatch);
|
||||
|
||||
const mapStateToProps = state_Ignored => {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
AdminNotes.propTypes = {
|
||||
requesting: PropTypes.bool,
|
||||
addNote: PropTypes.func.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
handleSubmit: PropTypes.func
|
||||
}
|
||||
handleSubmit: PropTypes.func,
|
||||
};
|
||||
|
||||
const AdminNotesForm = reduxForm({
|
||||
form: 'AdminNotes', // a unique identifier for this form
|
||||
validate, // <--- validation function given to redux-for
|
||||
enableReinitialize: true
|
||||
enableReinitialize: true,
|
||||
})(AdminNotes);
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AdminNotesForm);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user