Some cleaning
This commit is contained in:
parent
297a732676
commit
539e531272
@ -1,47 +1,72 @@
|
|||||||
import { faChevronUp } from "@fortawesome/free-solid-svg-icons";
|
import { faChevronUp } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
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 }) {
|
export default function ProductForm({ name, price, onFormChange, onSubmit, busy }) {
|
||||||
let [form, setForm] = useState({
|
let [form, setForm] = useState({
|
||||||
name: "",
|
name: "",
|
||||||
value: "",
|
value: "",
|
||||||
})
|
});
|
||||||
let [formBusy,setFormBusy] = useState(false);
|
let [errors, setErrors] = useState({
|
||||||
|
name: new Array<string>(),
|
||||||
|
price: new Array<string>(),
|
||||||
|
});
|
||||||
|
|
||||||
let nameChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
let nameChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
name = e.target.value;
|
name = e.target.value;
|
||||||
onNameChange(e.target.value);
|
setErrors(validateForm({name,price}));
|
||||||
|
onFormChange({ name, price });
|
||||||
}
|
}
|
||||||
let priceChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
let priceChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
price = e.target.value;
|
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()
|
e.preventDefault()
|
||||||
|
let currentErrors = validateForm({ name, price});
|
||||||
|
if (currentErrors.name.length === 0 && currentErrors.price.length === 0) {
|
||||||
onSubmit();
|
onSubmit();
|
||||||
}
|
}
|
||||||
formBusy = busy;
|
}
|
||||||
useEffect(() => {
|
|
||||||
setFormBusy(busy);
|
|
||||||
},[busy]);
|
|
||||||
return (
|
return (
|
||||||
<form>
|
<div>
|
||||||
<fieldset disabled={formBusy}>
|
|
||||||
<div className="mb-3">
|
<form onSubmit={submit}>
|
||||||
|
<fieldset disabled={busy}>
|
||||||
|
<div>
|
||||||
<label htmlFor="name">Name</label>
|
<label htmlFor="name">Name</label>
|
||||||
<input className="form-control" id="name" value={name} onChange={nameChanged}></input>
|
<input className={isValid("name")} id="name" value={name} onChange={nameChanged}></input>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label htmlFor="email">Price</label>
|
<Errors errors={errors.name} />
|
||||||
<input type="number" className="form-control" id="price" value={price} onChange={priceChanged}></input>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label htmlFor="price">Price</label>
|
||||||
|
<input type="number" className={isValid("price")} id="price" value={price} onChange={priceChanged}></input>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<button type="submit" className="btn btn-primary" onClick={submit}>
|
<Errors errors={errors.price} />
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<button type="submit" className="btn btn-primary">
|
||||||
<FontAwesomeIcon icon={faChevronUp} /> Submit
|
<FontAwesomeIcon icon={faChevronUp} /> Submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -13,22 +13,29 @@ export interface ProductListRowsProps {
|
|||||||
export interface ProductState {
|
export interface ProductState {
|
||||||
product: ProductListItem[]
|
product: ProductListItem[]
|
||||||
}
|
}
|
||||||
export interface ProductFormState {
|
export interface ProductFormEntry {
|
||||||
form: {
|
|
||||||
name: string,
|
name: string,
|
||||||
price: number,
|
price: number,
|
||||||
},
|
}
|
||||||
|
export interface ProductFormState {
|
||||||
|
form: ProductFormEntry,
|
||||||
errors: string[],
|
errors: string[],
|
||||||
busy: boolean,
|
busy: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateForm(form): string[] {
|
export function validateForm(form: ProductFormEntry) {
|
||||||
let errors: string[] = [];
|
let errors: {name: string[],price: string[]} = {
|
||||||
|
name: [],
|
||||||
|
price: [],
|
||||||
|
};
|
||||||
if (!form.name) {
|
if (!form.name) {
|
||||||
errors.push("Name required");
|
errors.name.push("Name required");
|
||||||
}
|
}
|
||||||
if (!form.price) {
|
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;
|
return errors;
|
||||||
}
|
}
|
@ -20,27 +20,10 @@ function CreateProduct() {
|
|||||||
let [busy, setBusy] = useState(false);
|
let [busy, setBusy] = useState(false);
|
||||||
let [errors, setErrors] = useState([""]);
|
let [errors, setErrors] = useState([""]);
|
||||||
|
|
||||||
const onNameChanged = (newName: string) => {
|
const onFormChanged = (form) => {
|
||||||
setForm(
|
setForm(form);
|
||||||
{
|
|
||||||
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 onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
if (validate()) {
|
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
try {
|
try {
|
||||||
const client = new ProductClient();
|
const client = new ProductClient();
|
||||||
@ -58,7 +41,6 @@ function CreateProduct() {
|
|||||||
setBusy(false);
|
setBusy(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto">
|
<div className="container mx-auto">
|
||||||
@ -72,8 +54,7 @@ function CreateProduct() {
|
|||||||
name={form.name}
|
name={form.name}
|
||||||
price={form.price}
|
price={form.price}
|
||||||
busy={busy}
|
busy={busy}
|
||||||
onNameChange={onNameChanged}
|
onFormChange={onFormChanged}
|
||||||
onPriceChange={onPriceChanged}
|
|
||||||
onSubmit={onSubmit} />
|
onSubmit={onSubmit} />
|
||||||
<ul>
|
<ul>
|
||||||
<Errors errors={errors}></Errors>
|
<Errors errors={errors}></Errors>
|
||||||
|
@ -45,20 +45,10 @@ function EditProduct({ productID }) {
|
|||||||
}
|
}
|
||||||
}, [productID]);
|
}, [productID]);
|
||||||
|
|
||||||
const onNameChanged = (newName: string) => {
|
const onFormChanged = (form) => {
|
||||||
setForm(
|
setForm(form);
|
||||||
{
|
|
||||||
name: newName,
|
|
||||||
price: form.price,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const onPriceChanged = (newPrice: number) => {
|
|
||||||
setForm({
|
|
||||||
name: form.name,
|
|
||||||
price: newPrice,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const validate = () => {
|
const validate = () => {
|
||||||
let errors: string[] = validateForm(form);
|
let errors: string[] = validateForm(form);
|
||||||
setErrors(errors);
|
setErrors(errors);
|
||||||
@ -97,8 +87,7 @@ function EditProduct({ productID }) {
|
|||||||
name={form.name}
|
name={form.name}
|
||||||
price={form.price}
|
price={form.price}
|
||||||
busy={busy}
|
busy={busy}
|
||||||
onNameChange={onNameChanged}
|
onFormChange={onFormChanged}
|
||||||
onPriceChange={onPriceChanged}
|
|
||||||
onSubmit={onSubmit} />
|
onSubmit={onSubmit} />
|
||||||
<ul>
|
<ul>
|
||||||
<Errors errors={errors}></Errors>
|
<Errors errors={errors}></Errors>
|
||||||
|
@ -83,11 +83,7 @@ class Product extends React.Component<{},ProductState> {
|
|||||||
try {
|
try {
|
||||||
const client = new ProductClient();
|
const client = new ProductClient();
|
||||||
await client.delete(productId);
|
await client.delete(productId);
|
||||||
// Remove the product in the state by filter()ing it
|
this.getProducts();
|
||||||
let product = this.state.product.filter(x => x.productID != productId);
|
|
||||||
this.setState({
|
|
||||||
product
|
|
||||||
})
|
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: "Deleted!",
|
title: "Deleted!",
|
||||||
text: "Product is deleted in database",
|
text: "Product is deleted in database",
|
||||||
@ -100,7 +96,13 @@ class Product extends React.Component<{},ProductState> {
|
|||||||
return (
|
return (
|
||||||
<div className="container px-4 mx-auto">
|
<div className="container px-4 mx-auto">
|
||||||
<h1>Products</h1>
|
<h1>Products</h1>
|
||||||
|
<Link href="/product/create">
|
||||||
|
<a className="btn btn-primary btn-large">
|
||||||
|
Create
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
<table className="table table-hover table-striped table-sm">
|
<table className="table table-hover table-striped table-sm">
|
||||||
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
@ -108,14 +110,10 @@ class Product extends React.Component<{},ProductState> {
|
|||||||
<th>Edit</th>
|
<th>Edit</th>
|
||||||
<th>Delete</th>
|
<th>Delete</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
</thead>
|
||||||
<ProductListItemRows products={this.state.product} onDelete={this.deleteProduct.bind(this)}>
|
<ProductListItemRows products={this.state.product} onDelete={this.deleteProduct.bind(this)}>
|
||||||
</ProductListItemRows>
|
</ProductListItemRows>
|
||||||
</table>
|
</table>
|
||||||
<Link href="/product/create">
|
|
||||||
<a className="btn btn-primary btn-large">
|
|
||||||
Create
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ namespace TestAppRuna.API
|
|||||||
{
|
{
|
||||||
if(ModelState.IsValid == false)
|
if(ModelState.IsValid == false)
|
||||||
{
|
{
|
||||||
return BadRequest();
|
return BadRequest(ModelState);
|
||||||
}
|
}
|
||||||
var customer = new Customer()
|
var customer = new Customer()
|
||||||
{
|
{
|
||||||
|
@ -65,7 +65,7 @@ namespace TestAppRuna.API
|
|||||||
{
|
{
|
||||||
if (ModelState.IsValid == false)
|
if (ModelState.IsValid == false)
|
||||||
{
|
{
|
||||||
return BadRequest();
|
return BadRequest(ModelState);
|
||||||
}
|
}
|
||||||
Product product = new Product
|
Product product = new Product
|
||||||
{
|
{
|
||||||
@ -84,7 +84,7 @@ namespace TestAppRuna.API
|
|||||||
{
|
{
|
||||||
if (ModelState.IsValid == false)
|
if (ModelState.IsValid == false)
|
||||||
{
|
{
|
||||||
return BadRequest();
|
return BadRequest(ModelState);
|
||||||
}
|
}
|
||||||
var data = await DB.Products
|
var data = await DB.Products
|
||||||
.Where(Q => Q.ProductID == id)
|
.Where(Q => Q.ProductID == id)
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user