Add webshop stuff

Signed-off-by: Jyri Genral <jyri.genral@protonmail.ch>
This commit is contained in:
Jyri Genral 2021-02-01 20:34:28 +01:00
parent d287175249
commit 4ac69b72c5
14 changed files with 144 additions and 21 deletions

1
data/productGroups.json Normal file
View file

@ -0,0 +1 @@
[{"name":"Maitotuotteet","subgroups":["Lehmänmaito","Vuohenmaito","Cheddar","Mozzarella"]},{"name":"Kukat","subgroups":["Leikkokukat","Rairuohot","Vehnä"]},{"name":"Lihatuotteet","subgroups":["Kana","Lammas","Possu","Kebabeläin"]}]

View file

@ -1,38 +1,160 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {observable} from 'mobx';
import {observer} from 'mobx-react';
import { observable, action, configure } from 'mobx';
import { observer } from 'mobx-react';
import "antd/es/layout/style";
import Layout from "antd/es/layout";
import "antd/es/menu/style";
import Menu from "antd/es/menu";
import "antd/es/card/style";
import Card from "antd/es/card";
import "antd/es/grid/style";
import { Row, Col } from "antd/es/grid";
import "antd/es/input/style";
import Input from "antd/es/input";
import { ShoppingCartOutlined } from '@ant-design/icons';
import * as productGroups from "../data/productGroups.json";
configure({ enforceActions: 'always' });
interface ProductGroup {
name: String,
subgroups: String[]
}
const PRODUCTGROUPS: ProductGroup[] = productGroups; // from GET productgroups
class AppState {
@observable timer = 0;
@observable productCardsOnDisplay: Array<ProductCard>;
constructor() {
setInterval(() => {
this.timer += 1;
}, 1000);
@action
setProductCardsOnDisplay(cards: Array<ProductCard>) {
this.productCardsOnDisplay = cards;
}
resetTimer() {
this.timer = 0;
async fetchProductCards() {
try {
const res = await fetch("http://localhost:8000/productCards");
const cards = await res.json();
this.setProductCardsOnDisplay(cards)
} catch (error) {
throw error;
}
}
constructor() {
this.setProductCardsOnDisplay([]);
this.fetchProductCards();
}
}
interface ProductCard {
name: string,
thumbnail: string,
display_price: string
}
@observer
class TimerView extends React.Component<{appState: AppState}, {}> {
class MainView extends React.Component<{ appState: AppState }, {}> {
productRows(products: ProductCard[]) {
const cardWidth = 180;
let ret: Array<JSX.Element> = [];
// TODO: there's probably thousand better ways than the initial copy paste rinse and repeat model below to form some rows .. PRs are welcomed
for (let index = 0; index < products.length; index += 4) {
let cols: Array<JSX.Element> = [
<Col offset={1}>
<Card hoverable style={{ width: cardWidth }} cover={<img alt="example" src={products[index].thumbnail} />}>
<Card.Meta title={products[index].name} description={products[index].display_price} />
</Card>
</Col>
];
if (index + 1 < products.length) {
cols.push(
<Col >
<Card hoverable style={{ width: cardWidth }} cover={<img alt="example" src={products[index + 1].thumbnail} />}>
<Card.Meta title={products[index + 1].name} description={products[index + 1].display_price} />
</Card>
</Col>);
}
if (index + 2 < products.length) {
cols.push(
<Col>
<Card hoverable style={{ width: cardWidth }} cover={<img alt="example" src={products[index + 2].thumbnail} />}>
<Card.Meta title={products[index + 2].name} description={products[index + 2].display_price} />
</Card>
</Col>);
}
if (index + 3 < products.length) {
cols.push(
<Col>
<Card hoverable style={{ width: cardWidth }} cover={<img alt="example" src={products[index + 3].thumbnail} />}>
<Card.Meta title={products[index + 3].name} description={products[index + 3].display_price} />
</Card>
</Col>);
}
ret.push(
<Row justify="start" gutter={[{ xs: 8, sm: 16, md: 24, lg: 32 }, { xs: 8, sm: 16, md: 24, lg: 32 }]}>
{cols}
</Row>
);
}
return ret;
}
render() {
return (
<div>
<button onClick={this.onReset}>
Seconds passed: {this.props.appState.timer}
</button>
</div>
<Layout>
<Layout.Header style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<img src="/static/logo.png" alt="logo" style={{ height: "inherit" }}></img>
<Menu mode="horizontal" theme="dark">
{PRODUCTGROUPS.map((group, groupindex) =>
<Menu.SubMenu key={groupindex} title={group.name}>
{group.subgroups.map((subgroup, subgroupindex) =>
<Menu.Item key={subgroupindex}>{subgroup}</Menu.Item>
)}
</Menu.SubMenu>
)}
<Menu.SubMenu title="Muuta tietoa">
<Menu.Item>Yhteystiedot</Menu.Item>
<Menu.Item>Aukioloajat</Menu.Item>
</Menu.SubMenu>
</Menu>
<Input.Search style={{ maxWidth: "20rem" }} />
</Layout.Header>
<Layout>
<Layout.Content>
{this.productRows(this.props.appState.productCardsOnDisplay)}
</Layout.Content>
<Layout.Sider theme="light">
<ShoppingCartOutlined style={{ fontSize: "6rem", width: "100%" }} />
</Layout.Sider>
</Layout>
<Layout.Footer>
<h4>Foobar</h4>
</Layout.Footer>
</Layout>
);
}
onReset = () => {
this.props.appState.resetTimer();
}
};
const appState = new AppState();
ReactDOM.render(<TimerView appState={appState} />, document.getElementById('root'));
ReactDOM.render(<MainView appState={appState} />, document.getElementById('root'));

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
static/prod/karhunkieli.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 MiB

BIN
static/prod/mokka.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 MiB

BIN
static/prod/oatly.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 MiB

BIN
static/prod/reko.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 MiB

BIN
static/prod/suopa.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
static/prod/t_mokka.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
static/prod/t_oatly.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
static/prod/t_reko.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
static/prod/t_suopa.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB