Skip to content

Commit

Permalink
Merge pull request #3 from dtinth/web/slot
Browse files Browse the repository at this point in the history
Webapp: Support multiple slots
  • Loading branch information
dtinth authored Sep 21, 2017
2 parents 64a9f5e + 041b716 commit 623118c
Show file tree
Hide file tree
Showing 11 changed files with 1,862 additions and 64 deletions.
1 change: 1 addition & 0 deletions webapp/.storybook/addons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@storybook/addon-actions/register'
11 changes: 11 additions & 0 deletions webapp/.storybook/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../src/index.css'
import 'pepjs'

import { configure } from '@storybook/react'

function loadStories () {
require('../src/Flipper.storybook')
require('../src/SlotSelector.storybook')
}

configure(loadStories, module)
10 changes: 8 additions & 2 deletions webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"promptpay-qr": "0.4.3",
"pepjs": "^0.4.3",
"promptpay-qr": "0.4.4",
"qrcode": "^0.9.0",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-pointable": "^1.1.0",
"react-scripts": "1.0.12"
},
"standard": {
Expand All @@ -16,9 +18,13 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"devDependencies": {
"@storybook/addon-actions": "^3.2.6",
"@storybook/react": "3.2.8",
"babel-eslint": "^7.2.3",
"standard": "^10.0.3"
}
Expand Down
107 changes: 86 additions & 21 deletions webapp/src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React, { Component } from 'react'

import Flipper from './Flipper'
import SlotSelector from './SlotSelector'
import _ from 'lodash'
import generatePayload from 'promptpay-qr'
import qr from 'qrcode'

Expand All @@ -23,53 +26,103 @@ class QRCode extends Component {
return
}
if (this.payload === payload) {
this.setState({ svg })
const src = 'data:image/svg+xml,' + encodeURIComponent(svg)
this.setState({ src })
}
})
}
render () {
return (
<div className='qrcode' dangerouslySetInnerHTML={{ __html: this.state.svg }} />
<div className='qrcode'>
<img src={this.state.src} alt='QR Code' />
</div>
)
}
}

const storageKeys = {
1: 'promptpayID',
2: 'promptpayID2',
3: 'promptpayID3',
4: 'promptpayID4'
}

function sanitizeId (id) {
return String(id).replace(/[^0-9]/g, '')
}

class App extends Component {
state = {
id: String(window.localStorage.promptpayID || ''),
amount: 0
state = this.getInitialState()
getInitialState () {
const slotNumber = +window.localStorage.promptPayActiveSlot || 1
const data = _.mapValues(storageKeys, (storageKey) => (
sanitizeId(window.localStorage[storageKey] || '')
))
return {
data: data,
slotNumber: slotNumber,
amount: 0,
flipped: false
}
}
onSet = () => {
const id = window.prompt('Your phone number', this.state.id)
const id = window.prompt('Your PromptPay ID (phone number or e-Wallet ID)', this.getId())
if (id != null) {
this.setState({ id })
window.localStorage.promptpayID = id
const sanitizedId = sanitizeId(id)
const n = this.state.slotNumber
this.setState({ data: { ...this.state.data, [n]: sanitizedId } })
window.localStorage[storageKeys[n]] = sanitizedId
}
}
onFlip = (flipped) => {
this.setState({ flipped })
}
onSelectSlot = (slot) => {
this.setState({ slotNumber: slot, flipped: false })
window.localStorage.promptPayActiveSlot = slot
if (window.ga) {
window.ga('send', 'event', 'Slot', 'select', `slot ${slot}`)
}
}
getId () {
return this.state.data[this.state.slotNumber]
}
renderQR () {
if (!this.state.id) {
const id = this.getId()
if (!id) {
return (
<div className='err'>
{t('กดที่นี่เพื่อตั้งค่าเบอร์โทรศัพท์', 'Tap to set PromptPay ID')}
</div>
<button className='err' onClick={this.onSet}>
<span className='err-text'>
{t('กดที่นี่เพื่อตั้งค่ารหัสพร้อมเพย์', 'Tap to set PromptPay ID')}
</span>
</button>
)
} else {
const payload = generatePayload(this.state.id, { amount: this.state.amount })
const payload = generatePayload(id, { amount: this.state.amount })
return (
<QRCode payload={payload} />
<div className='qrcode-container' onClick={this.onSet}>
<QRCode payload={payload} />
</div>
)
}
}
renderExplanation () {
if (!this.state.id) {
if (this.state.flipped) {
return (
<span>{t('เลือกตำแหน่งข้อมูล', 'Select a data slot')}</span>
)
}
const id = this.getId()
if (!id) {
return (
<span>{t('กดที่กล่องข้างบน เพื่อใส่เบอร์โทรศัพท์ที่ใช้รับเงิน', 'Tap above to get started')}</span>
<span>{t('กดที่กล่องข้างบน เพื่อใส่รหัสพร้อมเพย์ที่ใช้รับเงิน', 'Tap above to get started')}</span>
)
} else {
const id = this.state.id.replace(/[^0-9]/g, '')
return (
<span>
{id.length >= 13 ? (
{id.length >= 15 ? (
t('QR code มีรหัส e-Wallet ของคุณ', 'QR code contains your e-Wallet')
) : id.length >= 13 ? (
t('QR code มีเลขประจำตัวของคุณ', 'QR code contains your ID')
) : (
t('QR code มีเบอร์โทรศัพท์ของคุณ', 'QR code contains your phone number')
Expand All @@ -79,12 +132,24 @@ class App extends Component {
)
}
}
renderSlotSelector () {
return (
<SlotSelector
active={this.state.slotNumber}
data={this.state.data}
onSelect={this.onSelectSlot}
/>
)
}
render () {
return (
<div className='App'>
<div className='qr' onClick={this.onSet}>
{this.renderQR()}
</div>
<Flipper
front={this.renderQR()}
back={this.renderSlotSelector()}
flipped={this.state.flipped}
onFlip={this.onFlip}
/>
<div className='qr-explanation'>
{this.renderExplanation()}
</div>
Expand Down
Loading

0 comments on commit 623118c

Please sign in to comment.