From 533efe689eb20c27dad39a1682687b19626ef00c Mon Sep 17 00:00:00 2001 From: Giovanni Keppelen Date: Tue, 8 Aug 2017 11:24:06 -0300 Subject: [PATCH 1/4] add cashback staff and upload file to comprove expenses --- api/dashboard/index.js | 56 +++++++++++----- api/forecast/edit-expenses.js | 4 -- api/forecast/edit-revenue.js | 4 -- api/s3.js | 28 ++++++++ api/staff/index.js | 27 ++++++++ components/nav.js | 9 ++- components/staff-split.js | 61 +++++++++++++++++ package.json | 1 + pages/dashboard.js | 10 ++- pages/staff.js | 121 ++++++++++++++++++++++++++++++++++ server.js | 4 +- yarn.lock | 57 +++++++++++++++- 12 files changed, 350 insertions(+), 32 deletions(-) create mode 100644 api/s3.js create mode 100644 api/staff/index.js create mode 100644 components/staff-split.js create mode 100644 pages/staff.js diff --git a/api/dashboard/index.js b/api/dashboard/index.js index de53ffd..750bbd5 100644 --- a/api/dashboard/index.js +++ b/api/dashboard/index.js @@ -36,6 +36,13 @@ const findExpenses = (db, query, callback) => { }) } +const findCashbacks = (db, query, callback) => { + const collection = db.collection('staff') + collection.find({}).toArray((err, result) => { + callback(err, result) + }) +} + module.exports = (req, res) => { MongoClient.connect(url, (err, db) => { @@ -57,23 +64,40 @@ module.exports = (req, res) => { } }) - db.close() - return res.send({ - results: [ - { - name: 'Receitas', - tp: revenues.map(x => x.tp).reduce((a,b) => a + b, 0), - tr: revenues.map(x => x.tr).reduce((a,b) => a + b, 0) - }, - { - name: 'Despesas', - tp: expenses.map(x => x.tp).reduce((a,b) => a + b, 0), - tr: expenses.map(x => x.tr).reduce((a,b) => a + b, 0) - }, - ], - revenueForecasts: revenues, - expensesForecast: expenses + findCashbacks(db, {}, (err, cashbacks) => { + db.close() + const cashbacksCount = cashbacks.map(cash => { + return { + name: cash.staff, + tr: cash.pricing, + tp: cash.pricing, + } + }) + + return res.send({ + results: [ + { + name: 'Receitas', + tp: revenues.map(x => x.tp).reduce((a,b) => a + b, 0), + tr: revenues.map(x => x.tr).reduce((a,b) => a + b, 0) + }, + { + name: 'Despesas', + tp: expenses.map(x => x.tp).reduce((a,b) => a + b, 0), + tr: expenses.map(x => x.tr).reduce((a,b) => a + b, 0) + }, + { + name: 'Reembolsos', + tp: cashbacks.map(x => x.pricing).reduce((a,b) => a + b, 0), + tr: cashbacks.map(x => x.pricing).reduce((a,b) => a + b, 0) + }, + ], + revenueForecasts: revenues, + expensesForecast: expenses, + cashbacks: cashbacksCount + }) }) + }) }) diff --git a/api/forecast/edit-expenses.js b/api/forecast/edit-expenses.js index 7a9aa6d..df2ce3d 100644 --- a/api/forecast/edit-expenses.js +++ b/api/forecast/edit-expenses.js @@ -4,10 +4,6 @@ const assert = require('assert') const url = process.env.MONGO_DB; const update = (db, body, id, callback) => { - console.log( - body, - id - ) const collection = db.collection('expenses') collection.updateOne( { _id: ObjectId(id) }, diff --git a/api/forecast/edit-revenue.js b/api/forecast/edit-revenue.js index 09d5da0..3e9f1c0 100644 --- a/api/forecast/edit-revenue.js +++ b/api/forecast/edit-revenue.js @@ -4,10 +4,6 @@ const assert = require('assert') const url = process.env.MONGO_DB; const update = (db, body, id, callback) => { - console.log( - body, - id - ) const collection = db.collection('revenues') collection.updateOne( { _id: ObjectId(id) }, diff --git a/api/s3.js b/api/s3.js new file mode 100644 index 0000000..a929c7d --- /dev/null +++ b/api/s3.js @@ -0,0 +1,28 @@ +const aws = require('aws-sdk') +aws.config.region = 'us-east-1' + +module.exports = (req, res) => { + const s3 = new aws.S3(); + const fileName = `${new Date().getTime()}-${req.query['file-name']}`; + const fileType = req.query['file-type']; + const s3Params = { + Bucket: process.env.S3_BUCKET, + Key: fileName, + Expires: 60, + ContentType: fileType, + ACL: 'public-read' + }; + + s3.getSignedUrl('putObject', s3Params, (err, data) => { + if(err){ + console.log(err); + return res.end(); + } + const returnData = { + signedRequest: data, + url: `https://${process.env.S3_BUCKET}.s3.amazonaws.com/${fileName}` + }; + res.write(JSON.stringify(returnData)); + res.end(); + }); +} diff --git a/api/staff/index.js b/api/staff/index.js new file mode 100644 index 0000000..749f53a --- /dev/null +++ b/api/staff/index.js @@ -0,0 +1,27 @@ +const MongoClient = require('mongodb').MongoClient +const ObjectId = require('mongodb').ObjectId +const assert = require('assert') +const url = process.env.MONGO_DB; + +const insert = (db, body, callback) => { + const collection = db.collection('staff') + collection.insertOne({ staff: body.staff, pricing: parseFloat(body.pricing), url: body.url }, (err, result) => { + db.close() + callback(err, result) + }) +} + +module.exports = (req, res) => { + MongoClient.connect(url, function(err, db) { + if (req.body.staff) { + insert(db, req.body, (err, result) => { + if (err) { + return res.send({ status: false, message: result }) + } + return res.send({ status: true, message: result }) + }) + } else { + return res.send({ status: false, message: result }) + } + }) +} diff --git a/components/nav.js b/components/nav.js index 75c9052..0e3bd71 100644 --- a/components/nav.js +++ b/components/nav.js @@ -9,15 +9,18 @@ const Nav = () => ( FrontInBH Financial diff --git a/components/staff-split.js b/components/staff-split.js new file mode 100644 index 0000000..2f0691b --- /dev/null +++ b/components/staff-split.js @@ -0,0 +1,61 @@ +import React from 'react' + +export default class extends React.Component { + state = { + results: [ + { + name: 'Receitas', + tr: 0, + tp: 0 + }, + { + name: 'Despesas', + tr: 0, + tp: 0 + }, + { + name: 'Reembolsos', + tr: 0, + tp: 0 + } + ], + countStaff: 4 + } + + componentDidMount() { + fetch('/api/dashboard').then(response => { + return response.json() + }).then(data => { + const { results } = data + this.setState({ results }) + }) + } + + handleChange = (e) => { + const countStaff = e.target.value + this.setState({ countStaff }) + } + + render() { + const revenues = this.state.results.filter(r => r.name === 'Receitas') + const expenses = this.state.results.filter(r => r.name === 'Despesas') + const cashback = this.state.results.filter(r => r.name === 'Reembolsos') + const totalSplitReal = (revenues[0].tr - cashback[0].tr) - expenses[0].tr + const totalSplit = (revenues[0].tp - cashback[0].tp) - expenses[0].tp + return ( +
+ +

+ Real
+ {(totalSplitReal / this.state.countStaff) + .toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' })} +

+

+ Previsto
+ {(totalSplit / this.state.countStaff) + .toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' })} +

+
+ ) + } +} diff --git a/package.json b/package.json index d40f277..f37465e 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "start": "node server.js" }, "dependencies": { + "aws-sdk": "^2.94.0", "body-parser": "^1.17.2", "express": "^4.15.3", "mongodb": "^2.2.30", diff --git a/pages/dashboard.js b/pages/dashboard.js index 3aebabf..744b89e 100644 --- a/pages/dashboard.js +++ b/pages/dashboard.js @@ -3,6 +3,7 @@ import Link from 'next/link' import Head from '../components/head' import Nav from '../components/nav' import Chart from '../components/dashboard/chart' +import StaffSplit from '../components/staff-split' export default class Dashboard extends React.Component { state = { results: [], revenueForecasts: [], expensesForecast: [] } @@ -24,15 +25,22 @@ export default class Dashboard extends React.Component {
-
+
+
+

Lucro staff

+ +
+
+ +
diff --git a/pages/staff.js b/pages/staff.js new file mode 100644 index 0000000..372ac5d --- /dev/null +++ b/pages/staff.js @@ -0,0 +1,121 @@ +import Link from 'next/link' + +import Head from '../components/head' +import Nav from '../components/nav' +import StaffSplit from '../components/staff-split' +import 'whatwg-fetch' + +export default class Dashboard extends React.Component { + state = { message: '', staff: '', pricing: 0 } + componentDidMount() { + document.getElementById("file-input").onchange = () => { + const files = document.getElementById('file-input').files + const file = files[0] + if(file == null){ + return alert('No file selected.') + } + this.getSignedRequest(file) + } + } + + handleChange = (e) => { + const isNumber = /\d/.test(e.target.value); + + if (isNumber && e.target.name === 'pricing') { + this.setState({ [e.target.name]: e.target.value }) + } + if (!isNumber && e.target.name != 'pricing') { + this.setState({ [e.target.name]: e.target.value }) + } + } + + getSignedRequest = (file) => { + this.setState({ message: 'Salvando Dados...' }) + const xhr = new XMLHttpRequest(); + xhr.open('GET', `/api/sign-s3?staff=${this.state.staff}&file-name=${file.name}&file-type=${file.type}`); + xhr.onreadystatechange = () => { + if(xhr.readyState === 4){ + if(xhr.status === 200){ + const response = JSON.parse(xhr.responseText); + this.uploadFile(file, response.signedRequest, response.url); + } + else{ + alert('Could not get signed URL.'); + } + } + }; + xhr.send(); + } + + uploadFile = (file, signedRequest, url) => { + const xhr = new XMLHttpRequest(); + xhr.open('PUT', signedRequest); + xhr.onreadystatechange = () => { + if(xhr.readyState === 4){ + if(xhr.status === 200){ + fetch('/api/staff', { + method: 'post', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ staff: this.state.staff, pricing: this.state.pricing, url }) + }).then(res => { + return res.json() + }).then(response => { + if (response.status) { + this.setState({ message: 'Dados salvos com sucesso' }) + } else { + this.setState({ message: 'Ocorreu um erro, tente novamente' }) + } + setTimeout(() => { + this.setState({ staff: '', pricing: 0 }) + }, 2000) + }) + } + else{ + alert('Could not upload file.'); + } + } + }; + xhr.send(file); + } + + render() { + return ( +
+ +
+ ) + } +} diff --git a/server.js b/server.js index b7a159b..9e27d78 100644 --- a/server.js +++ b/server.js @@ -26,8 +26,10 @@ app.prepare() server.put('/api/forecast/revenue/:id', require('./api/forecast/edit-revenue')) server.get('/api/forecast/revenue', require('./api/forecast/revenue')) + server.post('/api/staff', require('./api/staff')) + server.get('/api/sign-s3', require('./api/s3')); + server.get('/api/dashboard', require('./api/dashboard')) - server.get('*', (req, res) => handle(req, res)) server.listen(PORT, (err) => { diff --git a/yarn.lock b/yarn.lock index a4633a0..a1480d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -177,6 +177,21 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" +aws-sdk@^2.94.0: + version "2.94.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.94.0.tgz#7043de3ef8c24cb6ab4bf235f08d87d84173e174" + dependencies: + buffer "4.9.1" + crypto-browserify "1.0.9" + events "^1.1.1" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.0.1" + xml2js "0.4.17" + xmlbuilder "4.2.1" + aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" @@ -944,7 +959,7 @@ buffer-xor@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" -buffer@^4.3.0: +buffer@4.9.1, buffer@^4.3.0: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" dependencies: @@ -1168,6 +1183,10 @@ cryptiles@2.x.x: dependencies: boom "2.x.x" +crypto-browserify@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" + crypto-browserify@^3.11.0: version "3.11.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.0.tgz#3652a0906ab9b2a7e0c3ce66a408e957a2485522" @@ -1531,7 +1550,7 @@ event-emitter@~0.3.5: d "1" es5-ext "~0.10.14" -events@^1.0.0: +events@^1.0.0, events@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -2137,6 +2156,10 @@ isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + js-tokens@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -2247,7 +2270,7 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash@^4.14.0, lodash@^4.16.4, lodash@^4.2.0, lodash@^4.5.1, lodash@^4.6.1, lodash@~4.17.4: +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.2.0, lodash@^4.5.1, lodash@^4.6.1, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -3223,6 +3246,10 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +sax@1.2.1, sax@>=0.6.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + "semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -3591,6 +3618,13 @@ unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + url@0.11.0, url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -3612,6 +3646,10 @@ utils-merge@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" +uuid@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + uuid@3.1.0, uuid@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" @@ -3761,6 +3799,19 @@ write-file-webpack-plugin@4.1.0: mkdirp "^0.5.1" moment "^2.11.2" +xml2js@0.4.17: + version "0.4.17" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" + dependencies: + sax ">=0.6.0" + xmlbuilder "^4.1.0" + +xmlbuilder@4.2.1, xmlbuilder@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" + dependencies: + lodash "^4.0.0" + xss-filters@1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/xss-filters/-/xss-filters-1.2.7.tgz#59fa1de201f36f2f3470dcac5f58ccc2830b0a9a" From 769d7eb6225229f5f142789207ebe0757a912aee Mon Sep 17 00:00:00 2001 From: Giovanni Keppelen Date: Tue, 8 Aug 2017 11:29:35 -0300 Subject: [PATCH 2/4] add favicon frontinbh --- components/head.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/head.js b/components/head.js index e437c37..5e3abd9 100644 --- a/components/head.js +++ b/components/head.js @@ -11,7 +11,7 @@ const Head = (props) => ( {props.title || ''} - + From f37a07afe41ccc14f86267226cf16fe2d5519d90 Mon Sep 17 00:00:00 2001 From: Giovanni Keppelen Date: Tue, 8 Aug 2017 11:29:55 -0300 Subject: [PATCH 3/4] change titles --- pages/dashboard.js | 2 +- pages/expense.js | 2 +- pages/index.js | 2 +- pages/revenue.js | 2 +- pages/staff.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pages/dashboard.js b/pages/dashboard.js index 744b89e..bfbc44a 100644 --- a/pages/dashboard.js +++ b/pages/dashboard.js @@ -20,7 +20,7 @@ export default class Dashboard extends React.Component { render() { return (
- +
diff --git a/server.js b/server.js index 9e27d78..e2e9799 100644 --- a/server.js +++ b/server.js @@ -27,6 +27,7 @@ app.prepare() server.get('/api/forecast/revenue', require('./api/forecast/revenue')) server.post('/api/staff', require('./api/staff')) + server.get('/api/staff', require('./api/staff/get')) server.get('/api/sign-s3', require('./api/s3')); server.get('/api/dashboard', require('./api/dashboard')) diff --git a/yarn.lock b/yarn.lock index a1480d3..f93f2f1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2270,7 +2270,7 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash@^4.0.0, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.2.0, lodash@^4.5.1, lodash@^4.6.1, lodash@~4.17.4: +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.5.1, lodash@^4.6.1, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"