123 lines
3.9 KiB
TypeScript
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>
|
|
}
|
|
} |