Some cleaning
This commit is contained in:
parent
297a732676
commit
539e531272
@ -1,47 +1,72 @@
|
||||
import { faChevronUp } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { validateForm } from "../lib/product";
|
||||
import Errors from "./Errors";
|
||||
|
||||
|
||||
export default function ProductForm({ name, price, onNameChange, onPriceChange, onSubmit, busy }) {
|
||||
let [form,setForm] = useState({
|
||||
export default function ProductForm({ name, price, onFormChange, onSubmit, busy }) {
|
||||
let [form, setForm] = useState({
|
||||
name: "",
|
||||
value: "",
|
||||
})
|
||||
let [formBusy,setFormBusy] = useState(false);
|
||||
let nameChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
});
|
||||
let [errors, setErrors] = useState({
|
||||
name: new Array<string>(),
|
||||
price: new Array<string>(),
|
||||
});
|
||||
|
||||
let nameChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
name = e.target.value;
|
||||
onNameChange(e.target.value);
|
||||
setErrors(validateForm({name,price}));
|
||||
onFormChange({ name, price });
|
||||
}
|
||||
let priceChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
price = e.target.value;
|
||||
onPriceChange(e.target.value);
|
||||
setErrors(validateForm({name,price}));
|
||||
onFormChange({ name, price });
|
||||
}
|
||||
let submit = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
let isValid = (prop) => {
|
||||
if(errors[prop].length > 0) {
|
||||
return "form-control is-invalid";
|
||||
} else {
|
||||
return "form-control is-valid";
|
||||
}
|
||||
}
|
||||
let submit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault()
|
||||
onSubmit();
|
||||
let currentErrors = validateForm({ name, price});
|
||||
if (currentErrors.name.length === 0 && currentErrors.price.length === 0) {
|
||||
onSubmit();
|
||||
}
|
||||
}
|
||||
formBusy = busy;
|
||||
useEffect(() => {
|
||||
setFormBusy(busy);
|
||||
},[busy]);
|
||||
|
||||
return (
|
||||
<form>
|
||||
<fieldset disabled={formBusy}>
|
||||
<div className="mb-3">
|
||||
<label htmlFor="name">Name</label>
|
||||
<input className="form-control" id="name" value={name} onChange={nameChanged}></input>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<label htmlFor="email">Price</label>
|
||||
<input type="number" className="form-control" id="price" value={price} onChange={priceChanged}></input>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<button type="submit" className="btn btn-primary" onClick={submit}>
|
||||
<FontAwesomeIcon icon={faChevronUp}/> Submit
|
||||
<div>
|
||||
|
||||
<form onSubmit={submit}>
|
||||
<fieldset disabled={busy}>
|
||||
<div>
|
||||
<label htmlFor="name">Name</label>
|
||||
<input className={isValid("name")} id="name" value={name} onChange={nameChanged}></input>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<Errors errors={errors.name} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="price">Price</label>
|
||||
<input type="number" className={isValid("price")} id="price" value={price} onChange={priceChanged}></input>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<Errors errors={errors.price} />
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<button type="submit" className="btn btn-primary">
|
||||
<FontAwesomeIcon icon={faChevronUp} /> Submit
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -13,22 +13,29 @@ export interface ProductListRowsProps {
|
||||
export interface ProductState {
|
||||
product: ProductListItem[]
|
||||
}
|
||||
export interface ProductFormEntry {
|
||||
name: string,
|
||||
price: number,
|
||||
}
|
||||
export interface ProductFormState {
|
||||
form: {
|
||||
name: string,
|
||||
price: number,
|
||||
},
|
||||
form: ProductFormEntry,
|
||||
errors: string[],
|
||||
busy: boolean,
|
||||
}
|
||||
|
||||
export function validateForm(form): string[] {
|
||||
let errors: string[] = [];
|
||||
export function validateForm(form: ProductFormEntry) {
|
||||
let errors: {name: string[],price: string[]} = {
|
||||
name: [],
|
||||
price: [],
|
||||
};
|
||||
if (!form.name) {
|
||||
errors.push("Name required");
|
||||
errors.name.push("Name required");
|
||||
}
|
||||
if (!form.price) {
|
||||
errors.push("Price required");
|
||||
errors.price.push("Price required");
|
||||
}
|
||||
if (form.price < 0) {
|
||||
errors.price.push("Price must be positive");
|
||||
}
|
||||
return errors;
|
||||
}
|
@ -18,45 +18,27 @@ function Errors({ errors }) {
|
||||
function CreateProduct() {
|
||||
let [form, setForm] = useState({ name: "", price: 0 });
|
||||
let [busy, setBusy] = useState(false);
|
||||
let [errors,setErrors] = useState([""]);
|
||||
let [errors, setErrors] = useState([""]);
|
||||
|
||||
const onNameChanged = (newName: string) => {
|
||||
setForm(
|
||||
{
|
||||
name: newName,
|
||||
price: form.price,
|
||||
}
|
||||
);
|
||||
}
|
||||
const onPriceChanged = (newPrice: number) => {
|
||||
setForm({
|
||||
name: form.name,
|
||||
price: newPrice,
|
||||
});
|
||||
}
|
||||
const validate = () => {
|
||||
let errors: string[] = validateForm(form);
|
||||
setErrors(errors);
|
||||
return errors.length == 0;
|
||||
const onFormChanged = (form) => {
|
||||
setForm(form);
|
||||
}
|
||||
const onSubmit = async () => {
|
||||
if (validate()) {
|
||||
setBusy(true);
|
||||
try {
|
||||
const client = new ProductClient();
|
||||
await client.post({
|
||||
name: form.name,
|
||||
price: form.price,
|
||||
})
|
||||
Swal.fire({
|
||||
title: "Submitted!",
|
||||
text: "Product is added in database",
|
||||
})
|
||||
} catch (error) {
|
||||
setBusy(true);
|
||||
try {
|
||||
const client = new ProductClient();
|
||||
await client.post({
|
||||
name: form.name,
|
||||
price: form.price,
|
||||
})
|
||||
Swal.fire({
|
||||
title: "Submitted!",
|
||||
text: "Product is added in database",
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,8 +54,7 @@ function CreateProduct() {
|
||||
name={form.name}
|
||||
price={form.price}
|
||||
busy={busy}
|
||||
onNameChange={onNameChanged}
|
||||
onPriceChange={onPriceChanged}
|
||||
onFormChange={onFormChanged}
|
||||
onSubmit={onSubmit} />
|
||||
<ul>
|
||||
<Errors errors={errors}></Errors>
|
||||
|
@ -45,20 +45,10 @@ function EditProduct({ productID }) {
|
||||
}
|
||||
}, [productID]);
|
||||
|
||||
const onNameChanged = (newName: string) => {
|
||||
setForm(
|
||||
{
|
||||
name: newName,
|
||||
price: form.price,
|
||||
}
|
||||
);
|
||||
}
|
||||
const onPriceChanged = (newPrice: number) => {
|
||||
setForm({
|
||||
name: form.name,
|
||||
price: newPrice,
|
||||
});
|
||||
const onFormChanged = (form) => {
|
||||
setForm(form);
|
||||
}
|
||||
|
||||
const validate = () => {
|
||||
let errors: string[] = validateForm(form);
|
||||
setErrors(errors);
|
||||
@ -97,8 +87,7 @@ function EditProduct({ productID }) {
|
||||
name={form.name}
|
||||
price={form.price}
|
||||
busy={busy}
|
||||
onNameChange={onNameChanged}
|
||||
onPriceChange={onPriceChanged}
|
||||
onFormChange={onFormChanged}
|
||||
onSubmit={onSubmit} />
|
||||
<ul>
|
||||
<Errors errors={errors}></Errors>
|
||||
|
@ -55,7 +55,7 @@ const ProductListItemRows: React.FunctionComponent<ProductListRowsProps> = ({ pr
|
||||
</tbody>
|
||||
)
|
||||
}
|
||||
class Product extends React.Component<{},ProductState> {
|
||||
class Product extends React.Component<{}, ProductState> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@ -83,11 +83,7 @@ class Product extends React.Component<{},ProductState> {
|
||||
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
|
||||
})
|
||||
this.getProducts();
|
||||
Swal.fire({
|
||||
title: "Deleted!",
|
||||
text: "Product is deleted in database",
|
||||
@ -100,22 +96,24 @@ class Product extends React.Component<{},ProductState> {
|
||||
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>
|
||||
<table className="table table-hover table-striped table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Price</th>
|
||||
<th>Edit</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<ProductListItemRows products={this.state.product} onDelete={this.deleteProduct.bind(this)}>
|
||||
</ProductListItemRows>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ namespace TestAppRuna.API
|
||||
{
|
||||
if(ModelState.IsValid == false)
|
||||
{
|
||||
return BadRequest();
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
var customer = new Customer()
|
||||
{
|
||||
|
@ -63,9 +63,9 @@ namespace TestAppRuna.API
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<string>> Post([FromBody] ProductCreateUpdateModel model)
|
||||
{
|
||||
if(ModelState.IsValid == false)
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
return BadRequest();
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
Product product = new Product
|
||||
{
|
||||
@ -82,14 +82,14 @@ namespace TestAppRuna.API
|
||||
[HttpPut("{id}")]
|
||||
public async Task<ActionResult<string>> Put(Guid id, [FromBody] ProductCreateUpdateModel model)
|
||||
{
|
||||
if(ModelState.IsValid == false)
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
return BadRequest();
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
var data = await DB.Products
|
||||
.Where(Q => Q.ProductID == id)
|
||||
.FirstOrDefaultAsync();
|
||||
if(data == null)
|
||||
if (data == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
@ -106,7 +106,7 @@ namespace TestAppRuna.API
|
||||
var data = await DB.Products
|
||||
.Where(Q => Q.ProductID == id)
|
||||
.FirstOrDefaultAsync();
|
||||
if(data == null)
|
||||
if (data == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
@ -128,7 +128,7 @@ namespace TestAppRuna.API
|
||||
[StringLength(255)]
|
||||
public string Name { get; set; }
|
||||
[Required]
|
||||
[Range(double.Epsilon,double.MaxValue)]
|
||||
[Range(double.Epsilon, double.MaxValue)]
|
||||
public decimal Price { get; set; }
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user