DevSampleExam/Client/components/ProductsComponent.tsx
2022-02-01 21:40:17 +01:00

123 lines
3.9 KiB
TypeScript

import * as React from 'react'
import { RouteComponentProps } from "react-router";
import { CartComponent } from './CartComponent';
import { ProductComponent } from './ProductComponent';
import { Product, User } from './types';
import { Map } from 'immutable'
import { ModalComponent } from './Modal';
export type Quantity = number
export type ProductsComponentState = {
products: { kind: "loaded", products: Product[] } | { kind: "loading" } | { kind: "error-or-not-found" } | { kind: "none" }
user: string,
cart: Map<Product, Quantity>
submit_status: { kind: "processing" } | { kind: "order_completed" } | { kind: "error" } | { kind: "none" }
}
export type ProductsComponentProps = {}
export class ProductsComponent extends React.Component<RouteComponentProps<ProductsComponentProps>, ProductsComponentState> {
constructor(props: RouteComponentProps<ProductsComponentProps>) {
super(props)
this.state = {
user: "",
cart: Map(),
submit_status: { kind: "none" },
products: { kind: "none" }
}
}
getProducts() {
this.setState(s => ({ ...s, products: { kind: "loading" } }), () => {
fetch(`/Cart/GetProducts`,
{
method: 'get', credentials: 'include',
headers: { 'content-type': 'application/json' }
}).then(async res => {
try {
if (!res.ok)
this.setState(s => ({ ...s, products: { kind: "error-or-not-found" } }))
let res1 = await res.json()
this.setState(s => ({ ...s, products: { kind: "loaded", products: res1 } }))
}
catch {
this.setState(s => ({ ...s, products: { kind: "error-or-not-found" } }))
}
})
})
}
placeOrder() {
let data_to_sent = {
user: { Name: this.state.user } as User,
products: this.state.cart.map((q, p) => ({ product: p, quantity: q })).valueSeq().toArray()
}
fetch(`/Cart/PlaceOrder`,
{
method: 'put', credentials: 'include',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(data_to_sent)
}).then(async res => {
try {
if (!res.ok)
this.setState(s => ({ ...s, submit_status: { kind: "error" } }))
let res1 = await res.json()
this.setState(s => ({ ...s, submit_status: { kind: "order_completed" } }))
}
catch {
this.setState(s => ({ ...s, submit_status: { kind: "error" } }))
}
})
}
componentWillMount() {
this.getProducts()
}
public render() {
if (this.state.products.kind != "loaded") {
return <p>{this.state.products.kind}</p>
}
return <div className='container-fluid row'>
<div className="row">
<div className='col-sm-6'>
<h2>Products</h2>
{this.state.products.products.map(p => <ProductComponent key={p.Id} product={p} product_id={p.Id} add_product={
() => this.setState(s => {
let s1 = { ...s }
if (!s1.cart.has(p)) {
s1.cart = s1.cart.set(p, 0)
}
s1.cart = s1.cart.set(p, s1.cart.get(p) + 1)
return s1
})
} />)}
</div>
<div className='col-sm-6'>
<CartComponent user={this.state.user}
cart={this.state.cart}
submit={() => {
this.setState(s => ({ ...s, submit_status: { kind: "processing" } }), () => {
this.placeOrder()
})
}}
update_cart={c => this.setState(s1 => ({ ...s1, cart: c }))}
update_user={s => this.setState(s1 => ({ ...s1, user: s }))} />
</div>
</div>
{this.state.submit_status.kind == "none" ? null : <ModalComponent
text={this.state.submit_status.kind}
close={() => this.setState(s => ({ ...s, submit_status: { kind: "none" } }))} />
}
</div>
}
}