130 lines
4.1 KiB
TypeScript
130 lines
4.1 KiB
TypeScript
import React from 'react';
|
|
import axios from 'axios';
|
|
import { ProductClient, ProductListItem } from '../../APIClient';
|
|
import { Layout } from '../shared/Layout';
|
|
import Swal from 'sweetalert2';
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
import { faEdit, faTrash } from '@fortawesome/free-solid-svg-icons';
|
|
import { useRouter } from 'next/router';
|
|
import Link from 'next/link';
|
|
import { DeleteProductProps, ProductDataProps, ProductListRowsProps, ProductState } from '../../interfaces/product';
|
|
|
|
const DeleteProductButton: React.FunctionComponent<DeleteProductProps> = ({ productID, onDelete }) => {
|
|
const onClickDelete = async () => {
|
|
const result = await Swal.fire({
|
|
title: 'Confirm delete?',
|
|
text: 'Delete product?',
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
})
|
|
if (result.isConfirmed) {
|
|
onDelete(productID);
|
|
}
|
|
}
|
|
return (
|
|
<button className="btn btn-danger btn-sm" onClick={onClickDelete}>
|
|
<FontAwesomeIcon icon={faTrash} />
|
|
</button>
|
|
);
|
|
}
|
|
const EditProductButton: React.FunctionComponent<ProductDataProps> = ({ productID }) => {
|
|
const router = useRouter();
|
|
return (
|
|
<Link href={`/product/edit/${productID}`}>
|
|
<a className="btn btn-warning btn-sm">
|
|
<FontAwesomeIcon icon={faEdit} />
|
|
</a>
|
|
</Link>
|
|
);
|
|
}
|
|
const ProductListItemRows: React.FunctionComponent<ProductListRowsProps> = ({ products, onDelete }) => {
|
|
let rows = products.map(x => {
|
|
return (
|
|
<tr>
|
|
<td>{x.productID}</td>
|
|
<td>{x.name}</td>
|
|
<td>{x.price}</td>
|
|
<td><EditProductButton productID={x.productID}></EditProductButton></td>
|
|
<td><DeleteProductButton productID={x.productID} onDelete={onDelete}></DeleteProductButton></td>
|
|
</tr>
|
|
);
|
|
})
|
|
return (
|
|
<tbody>
|
|
{rows}
|
|
</tbody>
|
|
)
|
|
}
|
|
class Product extends React.Component<{},ProductState> {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
product: [],
|
|
}
|
|
}
|
|
async componentDidMount() {
|
|
this.getProducts();
|
|
}
|
|
async getProducts() {
|
|
try {
|
|
const client = new ProductClient();
|
|
let data = await client.getAll();
|
|
console.log(data);
|
|
this.setState({
|
|
product: data
|
|
});
|
|
} catch (error) {
|
|
this.setState({
|
|
product: [],
|
|
});
|
|
}
|
|
}
|
|
async deleteProduct(productId) {
|
|
try {
|
|
const client = new ProductClient();
|
|
await client.delete(productId);
|
|
// Remove the product in the state by filter()ing it
|
|
let product = this.state.product.filter(x => x.productID != productId);
|
|
this.setState({
|
|
product
|
|
})
|
|
Swal.fire({
|
|
title: "Deleted!",
|
|
text: "Product is deleted in database",
|
|
})
|
|
} catch (error) {
|
|
alert(error);
|
|
}
|
|
}
|
|
render() {
|
|
return (
|
|
<div className="container px-4 mx-auto">
|
|
<h1>Products</h1>
|
|
<table className="table table-hover table-striped table-sm">
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Name</th>
|
|
<th>Price</th>
|
|
<th>Edit</th>
|
|
<th>Delete</th>
|
|
</tr>
|
|
<ProductListItemRows products={this.state.product} onDelete={this.deleteProduct.bind(this)}>
|
|
</ProductListItemRows>
|
|
</table>
|
|
<Link href="/product/create">
|
|
<a className="btn btn-primary btn-large">
|
|
Create
|
|
</a>
|
|
</Link>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default function ProductPage() {
|
|
return (
|
|
<Layout title="Products">
|
|
<Product></Product>
|
|
</Layout>
|
|
)
|
|
} |