@@ -1,3 +1,8 @@ | |||
# Breakups-Webapp | |||
https://breakups-webapp.herokuapp.com/ | |||
[![Build Status](https://travis-ci.org/binhonglee/breakups-webapp.svg?branch=master)](https://travis-ci.org/binhonglee/breakups-webapp) | |||
[![Dependency Status](https://gemnasium.com/badges/github.com/binhonglee/Breakups.svg)](https://gemnasium.com/github.com/binhonglee/Breakups) | |||
Basic webapp that implements the [Breakups API](https://github.com/binhonglee/Breakups) functionality. |
@@ -13,15 +13,5 @@ | |||
You need to enable JavaScript to run this app. | |||
</noscript> | |||
<div id="root"></div> | |||
<!-- | |||
This HTML file is a template. | |||
If you open it directly in the browser, you will see an empty page. | |||
You can add webfonts, meta tags, or analytics to this file. | |||
The build step will place the bundled scripts into the <body> tag. | |||
To begin the development, run `npm start` or `yarn start`. | |||
To create a production bundle, use `npm run build` or `yarn build`. | |||
--> | |||
</body> | |||
</html> |
@@ -1,34 +0,0 @@ | |||
.App { | |||
text-align: center; | |||
} | |||
.App-logo { | |||
animation: App-logo-spin infinite 20s linear; | |||
height: 80px; | |||
} | |||
.App-header { | |||
background-color: #222; | |||
height: 150px; | |||
padding: 20px; | |||
color: white; | |||
} | |||
.App-title { | |||
font-size: 1.5em; | |||
} | |||
.App-intro { | |||
font-size: large; | |||
} | |||
@keyframes App-logo-spin { | |||
from { transform: rotate(0deg); } | |||
to { transform: rotate(360deg); } | |||
} | |||
.form { | |||
/*text-align: left;*/ | |||
align-items: left; | |||
align-self:left; | |||
} |
@@ -1,47 +1,109 @@ | |||
import React, { Component } from 'react'; | |||
import People from './Components/People'; | |||
import PaymentChain from './Components/PaymentChain'; | |||
import './App.css'; | |||
var https = require('https'); | |||
class App extends Component { | |||
constructor() { | |||
super(); | |||
this.state = { | |||
peoples: [] | |||
peoples: [], | |||
info: [], | |||
paymentChain: [] | |||
} | |||
} | |||
render() { | |||
return ( | |||
<div className="App"> | |||
Breakups | |||
<br/> | |||
<br/> | |||
<h1>Breakups</h1> | |||
<h3>Easy way to split bills among multiple people.</h3> | |||
<form onSubmit={this.populatePeople.bind(this)}> | |||
Number of people: <input type="text" ref="noOfPeople"/> <input type="submit" value="Submit" /> | |||
</form> | |||
<br/> | |||
<br/> | |||
{this.state.peoples} | |||
<input type="submit" value="Get Payment Chain"/> | |||
<input type="submit" value="Send email reminder"/> | |||
<br/> | |||
<PaymentChain paymentChain={this.state.paymentChain} /> | |||
<br/> | |||
</div> | |||
); | |||
} | |||
getPaymentChain() { | |||
let request = {}; | |||
let users = []; | |||
for (var key in this.state.info) { | |||
if (isNaN(this.state.info[key].amount)) { | |||
alert('Amount must be number!'); | |||
return; | |||
} | |||
let user = {}; | |||
user.name = this.state.info[key].name; | |||
user.email = this.state.info[key].email; | |||
user.amount = parseInt(this.state.info[key].amount, 10); | |||
users.push(user); | |||
} | |||
request.users = users; | |||
this.httpsPost(request, result => { | |||
let existingState = this.state; | |||
existingState.paymentChain = JSON.parse("[" + result + "]")[0]; | |||
this.setState(existingState); | |||
}) | |||
} | |||
populatePeople(e) { | |||
let peoples = [] | |||
let info = [] | |||
if (isNaN(this.refs.noOfPeople.value)) { | |||
alert('Please input number!'); | |||
if (isNaN(this.refs.noOfPeople.value) || this.refs.noOfPeople.value <= 2) { | |||
alert('Please input number larger than 2!'); | |||
} else { | |||
for (var i = 0; i < this.refs.noOfPeople.value; i++) { | |||
peoples.push (<People key={i} people={(i+1)} />); | |||
this.setState({peoples:peoples}); | |||
} | |||
info.push({}); | |||
peoples.push(<People key={i} id={i} people={(i+1)} info={this.updateInfo.bind(this)} />); | |||
} | |||
peoples.push(<input key="paymentChain" type="submit" value="Get Payment Chain" onClick={this.getPaymentChain.bind(this)}/>); | |||
peoples.push(<input key="email" type="submit" value="Send email reminder (non-functional yet)"/>); | |||
this.setState({peoples:peoples, info:info}); | |||
} | |||
e.preventDefault(); | |||
} | |||
updateInfo(e) { | |||
let existingState = this.state; | |||
existingState.info[e.id] = e.info; | |||
this.setState(existingState); | |||
} | |||
httpsPost(data, callback) { | |||
var post_options = { | |||
host: 'breakups.herokuapp.com', | |||
path: '/paymentChain', | |||
method: 'POST', | |||
headers: { | |||
'Content-Type': 'application/json', | |||
'Content-Length': Buffer.byteLength(JSON.stringify(data)) | |||
} | |||
}; | |||
var post_req = https.request(post_options, res => { | |||
res.setEncoding('utf8'); | |||
var returnData = ""; | |||
res.on('data', chunk => { | |||
returnData += chunk; | |||
}); | |||
res.on('end', () => { | |||
console.log(returnData) | |||
callback(returnData); | |||
}); | |||
}); | |||
post_req.write(JSON.stringify(data)); | |||
post_req.end(); | |||
} | |||
} | |||
export default App; |
@@ -0,0 +1,14 @@ | |||
import React, { Component } from 'react'; | |||
class Payment extends Component { | |||
render() { | |||
return ( | |||
<div className="Payment"> | |||
<br/> | |||
{this.props.payment.from} ----{this.props.payment.amount}----> {this.props.payment.to} | |||
</div> | |||
) | |||
} | |||
} | |||
export default Payment; |
@@ -0,0 +1,23 @@ | |||
import React, { Component } from 'react'; | |||
import Payment from './Payment'; | |||
class PaymentChain extends Component { | |||
render() { | |||
let payments; | |||
if (this.props.paymentChain) { | |||
payments = this.props.paymentChain.map(payment => { | |||
return ( | |||
<Payment key={payment.from} payment={payment} /> | |||
); | |||
}); | |||
} | |||
return ( | |||
<div className="PaymentChain"> | |||
{payments} | |||
</div> | |||
); | |||
} | |||
} | |||
export default PaymentChain; |
@@ -6,14 +6,27 @@ class People extends Component { | |||
<div className="People"> | |||
<form className="form"> | |||
Person {this.props.people}<br/> | |||
Name: <input type = "text" ref="name"/><br/> | |||
Email: <input type = "text" ref="email"/><br/> | |||
Amount: <input type = "text" ref="amount"/><br/> | |||
Name: <input type = "text" ref="name" onBlur={this.updateProps.bind(this)}/><br/> | |||
Email: <input type = "text" ref="email" onBlur={this.updateProps.bind(this)}/><br/> | |||
Amount: <input type = "text" ref="amount" onBlur={this.updateProps.bind(this)}/><br/> | |||
</form> | |||
<br/> | |||
</div> | |||
); | |||
} | |||
updateProps() { | |||
let req = { | |||
name: this.refs.name.value, | |||
email: this.refs.email.value, | |||
amount: this.refs.amount.value | |||
}; | |||
let infoToSend = { | |||
id: this.props.id, | |||
info: req | |||
} | |||
this.props.info(infoToSend); | |||
} | |||
} | |||
export default People; |