Skip to content

Commit b6de203

Browse files
committed
Rewrote the codebase to Typescript
Typescript is a lot nicer to work with so I rewrote the App to it. I still have to make interfaces for products and some other any typed variables.
1 parent d268319 commit b6de203

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1273
-1001
lines changed

.editorconfig

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# http://editorconfig.org/
2+
3+
root = true
4+
5+
[*]
6+
end_of_line = lf
7+
insert_final_newline = true
8+
trim_trailing_whitespace = true
9+
charset = utf-8
10+
11+
[*.{js,jsx,ts,tsx,json,html,scss,css}]
12+
indent_style = space
13+
indent_size = 4
14+
15+
[{package.json,typings.json,tsconfig.json}]
16+
indent_size = 2

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
.DS_Store
22
node_modules/
3+
config.js
4+
bundle/

index.html

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
6+
<title>FooBar</title>
7+
<link rel="stylesheet" type="text/css" href="/static/css/font-awesome.min.css"/>
8+
<link rel="stylesheet" type="text/css" href="/static/css/main.css"/>
9+
</head>
10+
<body>
11+
<div id="app"></div>
12+
<script src="/static/js/socks.js"></script>
13+
<script src="/static/js/thunderpush.js"></script>
14+
<script src="bundle.js"></script>
15+
</body>
16+
</html>

package.json

+42-24
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"version": "0.0.1",
44
"description": "Foobar Kiosk application.",
55
"scripts": {
6-
"start": "node server.js"
6+
"start": "node server.js",
7+
"bundle": "NODE_ENV=production webpack --progress --hide-modules --config webpack.prod.config.js"
78
},
89
"repository": {
910
"type": "git",
@@ -13,31 +14,48 @@
1314
"bugs": {
1415
"url": "https://github.com/uppsaladatavetare/foobar-kiosk/issues"
1516
},
16-
"dependencies": {
17-
"isomorphic-fetch": "^2.2.0",
18-
"react": "^0.14.0",
19-
"react-dom": "^0.14.0",
20-
"react-redux": "^4.0.0",
21-
"redux": "^3.0.0",
22-
"redux-logger": "^2.0.2",
23-
"redux-router": "^1.0.0-beta4",
24-
"redux-thunk": "^1.0.0"
25-
},
2617
"devDependencies": {
27-
"babel-core": "^6.1.4",
28-
"babel-loader": "^6.1.0",
29-
"babel-plugin-react-transform": "^1.1.0",
30-
"babel-plugin-transform-object-rest-spread": "^6.1.4",
31-
"babel-preset-es2015": "^6.1.4",
32-
"babel-preset-react": "^6.1.4",
18+
"@types/classnames": "0.0.28",
19+
"@types/es6-promise": "0.0.31",
20+
"@types/isomorphic-fetch": "0.0.30",
21+
"@types/node": "^6.0.38",
22+
"@types/object-assign": "^4.0.28",
23+
"@types/react": "^0.14.33",
24+
"@types/react-dom": "^0.14.16",
25+
"@types/react-redux": "^4.4.31",
26+
"@types/redux": "^3.5.28",
27+
"@types/redux-logger": "^2.6.31",
28+
"@types/redux-thunk": "^2.1.30",
29+
"autoprefixer": "^6.4.0",
30+
"awesome-typescript-loader": "^2.1.1",
3331
"classnames": "^2.2.0",
32+
"css-loader": "^0.24.0",
3433
"expect": "^1.6.0",
35-
"express": "^4.13.3",
36-
"node-libs-browser": "^0.5.2",
37-
"react-transform-hmr": "^1.0.0",
38-
"redux-devtools": "^2.1.5",
39-
"webpack": "^1.9.11",
40-
"webpack-dev-middleware": "^1.2.0",
41-
"webpack-hot-middleware": "^2.2.0"
34+
"isomorphic-fetch": "^2.2.0",
35+
"node-sass": "^3.8.0",
36+
"object-assign": "^4.1.0",
37+
"postcss": "^5.1.2",
38+
"postcss-loader": "^0.11.0",
39+
"react": "^15.3.1",
40+
"react-dom": "^15.3.1",
41+
"react-hot-loader": "^1.3.0",
42+
"react-redux": "^4.0.0",
43+
"redux": "^3.5.0",
44+
"redux-devtools": "^3.3.1",
45+
"redux-logger": "^2.0.2",
46+
"redux-router": "^2.1.2",
47+
"redux-thunk": "^2.1.0",
48+
"requirejs": "^2.2.0",
49+
"sass-loader": "^4.0.0",
50+
"style-loader": "^0.13.1",
51+
"tslint": "^3.14.0",
52+
"tslint-loader": "^2.1.5",
53+
"typed-css-modules": "^0.1.12",
54+
"typed-css-modules-loader": "0.0.4",
55+
"typescript": "^2.0.0",
56+
"webpack": "^1.13.1",
57+
"webpack-dev-middleware": "^1.6.1",
58+
"webpack-dev-server": "^1.14.1",
59+
"webpack-hot-middleware": "^2.10.0"
4260
}
4361
}

server.js

+28-19
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,33 @@
11
var webpack = require('webpack');
2-
var webpackDevMiddleware = require('webpack-dev-middleware');
3-
var webpackHotMiddleware = require('webpack-hot-middleware');
2+
var WebpackDevServer = require('webpack-dev-server');
43
var config = require('./webpack.config');
54

6-
var express = new require('express');
7-
var app = express();
8-
var port = 3000;
5+
new WebpackDevServer(webpack(config), {
6+
publicPath: config.output.publicPath,
7+
inline: true,
8+
hot: true,
9+
historyApiFallback: true,
10+
stats: {
11+
hideModules: true,
12+
colors: true,
13+
hash: false,
14+
version: false,
15+
timings: true,
16+
assets: true,
17+
chunks: false,
18+
modules: false,
19+
reasons: false,
20+
children: false,
21+
source: false,
22+
errors: true,
23+
errorDetails: true,
24+
warnings: true,
25+
publicPath: false
26+
}
27+
}).listen(3000, '0.0.0.0', function (err, result) {
28+
if (err) {
29+
console.log(err);
30+
}
931

10-
var compiler = webpack(config);
11-
app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }));
12-
app.use(webpackHotMiddleware(compiler));
13-
app.use(express.static('src/static'));
14-
app.get("/", function(req, res) {
15-
res.sendFile(__dirname + '/src/index.html');
16-
});
17-
18-
app.listen(port, 'localhost', function(error) {
19-
if (error) {
20-
console.error(error);
21-
} else {
22-
console.info("==> 🌎 Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port);
23-
}
32+
console.log('Listening at http://localhost:3000');
2433
});

src/App.tsx

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
declare const Thunder: any;
2+
3+
import * as React from "react";
4+
import * as ReactDOM from "react-dom";
5+
import { render } from "react-dom";
6+
import { Provider } from "react-redux";
7+
import { connect } from "react-redux";
8+
9+
import configureStore from "store/configureStore";
10+
import { login } from "actions/account";
11+
import { requestPurchase, clearPurchase, endPurchase } from "actions/purchase";
12+
import { addProduct, removeProduct, selectProduct, increaseProductQty, changePage } from "actions/product";
13+
14+
import ProductList from "components/ProductList";
15+
import PurchaseButton from "components/PurchaseButton";
16+
import AccountBar from "components/AccountBar";
17+
import ButtonBar from "components/ButtonBar";
18+
import LoadingBox from "components/LoadingBox";
19+
20+
interface Props {
21+
dispatch: Function;
22+
products: any;
23+
account: any;
24+
purchase: any;
25+
}
26+
27+
class App extends React.Component<Props, {}> {
28+
componentDidMount() {
29+
const { dispatch } = this.props;
30+
// dispatch(login("154464990"));
31+
Thunder.connect("localhost:8080", "foobar", ["products", "cards"]);
32+
Thunder.listen((data: any) => {
33+
if (data.channel === "products") {
34+
dispatch(addProduct(JSON.parse(data.payload)));
35+
} else if (data.channel === "cards") {
36+
dispatch(login(data.payload));
37+
}
38+
});
39+
}
40+
41+
addRandomProduct() {
42+
let eans = [
43+
"7310500088853",
44+
"7340083438684",
45+
"7611612221351",
46+
"7310500114934",
47+
"7310070765840",
48+
"7315360010754",
49+
"7622300342753"
50+
];
51+
52+
let randomIndex = Math.floor(Math.random() * eans.length);
53+
this.props.dispatch(addProduct(eans[randomIndex]));
54+
}
55+
56+
render() {
57+
const { dispatch, products, account, purchase } = this.props;
58+
59+
let selected = products.products.filter((product: any) => {
60+
return product.selected;
61+
}).length;
62+
63+
if ((purchase.state === "ONGOING" || purchase.state === "PENDING")) {
64+
return (
65+
<div id="container">
66+
<ProductList
67+
products={products}
68+
onSelect={(ean: string) => dispatch(selectProduct(ean))}/>
69+
<span id="trash" className="button" onClick={() => dispatch(clearPurchase())}>
70+
<i className="fa fa-times"></i>
71+
</span>
72+
<span style={{ position: "absolute", bottom: 0, zIndex: 99 }} className="button" onClick={() => this.addRandomProduct()}>
73+
<i className="fa fa-plus"></i>
74+
</span>
75+
<div id="sidebar">
76+
<AccountBar {...account} />
77+
<div id="menubox"></div>
78+
<PurchaseButton
79+
products={products}
80+
purchaseState={purchase.state}
81+
accountBalance={account.balance}
82+
onPurchase={() => dispatch(requestPurchase())}
83+
/>
84+
</div>
85+
<ButtonBar
86+
onIncrease={() => dispatch(increaseProductQty(1))}
87+
onDecrease={() => dispatch(increaseProductQty(-1))}
88+
onRemove={() => dispatch(removeProduct())}
89+
onScrollUp={() => dispatch(changePage(-1))}
90+
onScrollDown={() => dispatch(changePage(1))}
91+
active={selected > 0}
92+
scrollUpActive={products.page > 0}
93+
scrollDownActive={products.page < products.maxPage}
94+
/>
95+
<LoadingBox loading={purchase.state === "PENDING"}/>
96+
</div>
97+
);
98+
}
99+
else if (purchase.state === "ONGOING") {
100+
return (
101+
<div id="container" className="white">
102+
<div className="loading">
103+
<div className="rekt1"/>
104+
<div className="rekt2"/>
105+
<div className="rekt3"/>
106+
<div className="rekt4"/>
107+
<div className="rekt5"/>
108+
</div>
109+
</div>
110+
);
111+
}
112+
else if (purchase.state === "FINALIZED") {
113+
return (
114+
<div id="container">
115+
<div id="start">
116+
<div>Total cost of purchase was {purchase.cost} kr.</div>
117+
<span className="button" onClick={() => dispatch(endPurchase())}>Okay</span>
118+
</div>
119+
</div>
120+
);
121+
}
122+
else /* if(purchase.state === "WAITING") */ {
123+
return (
124+
<div id="container">
125+
<div id="start">
126+
<span style={{ position: "absolute", bottom: 0, zIndex: 99 }} className="button" onClick={() => this.addRandomProduct()}>
127+
<i className="fa fa-plus"></i>
128+
</span>
129+
<div>Blip a card linked with your account.</div>
130+
<div>or</div>
131+
<div>Scan a product to start a cash payment.</div>
132+
<span className="button" onClick={() => dispatch(login("154464990"))}>I like pies</span>
133+
</div>
134+
<LoadingBox loading={account.request}/>
135+
</div>
136+
);
137+
}
138+
}
139+
}
140+
141+
function mapStateToProps(state: any) {
142+
const { products, account, purchase } = state;
143+
144+
return {
145+
products,
146+
account,
147+
purchase
148+
};
149+
}
150+
151+
const store = configureStore();
152+
const AppWithState = connect(mapStateToProps)(App);
153+
154+
ReactDOM.render((
155+
<Provider store={store}>
156+
<AppWithState/>
157+
</Provider>
158+
), document.getElementById("app"));

src/actions/account.js

-46
This file was deleted.

0 commit comments

Comments
 (0)