Skip to content

Commit 7bd4f87

Browse files
committed
adjust product layout
1 parent 75189f0 commit 7bd4f87

File tree

4 files changed

+142
-112
lines changed

4 files changed

+142
-112
lines changed

src/Web/package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"react-bootstrap-table2-paginator": "^2.1.2",
3030
"react-bootstrap-table2-toolkit": "^2.1.3",
3131
"react-dom": "17.0.1",
32+
"react-hook-form": "^6.15.1",
3233
"webpack": "^5.19.0"
3334
}
3435
}

src/Web/pages/product/[id].js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { useRouter } from "next/router";
2+
import { useForm } from "react-hook-form";
3+
4+
// https://react-hook-form.com/get-started
5+
const Product = () => {
6+
const router = useRouter();
7+
const { id } = router.query;
8+
9+
const { register, handleSubmit, watch, errors } = useForm();
10+
const onSubmit = (data) => console.log(data);
11+
12+
return (
13+
<form onSubmit={handleSubmit(onSubmit)}>
14+
<input name="id" defaultValue={id} ref={register({ required: true })} />
15+
{errors.id && <span>This field is required</span>}
16+
17+
<input type="submit" />
18+
</form>
19+
);
20+
};
21+
22+
export default Product;

src/Web/pages/products.js

Lines changed: 114 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import React, { useCallback, useState } from "react";
2+
import { useRouter } from "next/router";
3+
import Link from "next/link";
4+
25
import {
36
Container,
47
Card,
@@ -17,7 +20,11 @@ import filterFactory, {
1720
} from "react-bootstrap-table2-filter";
1821

1922
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
20-
import { faPlus, faEdit, faTrash } from "@fortawesome/free-solid-svg-icons";
23+
import {
24+
faPlus,
25+
faEraser,
26+
faFileExcel,
27+
} from "@fortawesome/free-solid-svg-icons";
2128

2229
import _ from "lodash";
2330
import axios from "axios";
@@ -26,12 +33,18 @@ import moment from "moment";
2633
const ApiUrl = "http://localhost:5002/api/products";
2734

2835
const Products = (props) => {
36+
const router = useRouter();
2937
const [page, setPage] = useState(1);
3038
const [sizePerPage, setSizePerPage] = useState(10);
3139
const [products, setProducts] = useState([]);
3240
const [totalSize, setTotalSize] = useState(0);
3341
const [selectedProduct, setSelectedProduct] = useState({});
3442

43+
let nameFilter;
44+
let priceFilter;
45+
let quantityFilter;
46+
let createdFilter;
47+
3548
const fetchData = useCallback(
3649
async (type, { page, sizePerPage, filters, sortField, sortOrder }) => {
3750
var queryModel = {
@@ -94,12 +107,18 @@ const Products = (props) => {
94107
setSelectedProduct(row);
95108
};
96109

97-
const handleEdit = () => {
98-
console.log(selectedProduct);
99-
};
100-
101-
const handleDelete = () => {
102-
console.log(selectedProduct);
110+
const rowEdit = (cell, row, rowIndex, formatExtraData) => {
111+
return (
112+
<>
113+
<Link href={`product/${row.id}`}>
114+
<Button variant="outline-warning" size="sm">Edit</Button>
115+
</Link>
116+
&nbsp;
117+
<Link href={`product/${row.id}`}>
118+
<Button variant="outline-danger" size="sm">Delete</Button>
119+
</Link>
120+
</>
121+
);
103122
};
104123

105124
const handleClearFilters = () => {
@@ -125,6 +144,79 @@ const Products = (props) => {
125144
onSelect: rowSelect,
126145
};
127146

147+
const columns = [
148+
{
149+
dataField: "id",
150+
text: "Product id",
151+
hidden: true,
152+
},
153+
{
154+
dataField: "name",
155+
text: "Product name",
156+
filter: textFilter({
157+
getFilter: (filter) => {
158+
nameFilter = filter;
159+
},
160+
}),
161+
sort: true,
162+
},
163+
{
164+
dataField: "cost",
165+
text: "Product price",
166+
filter: numberFilter({
167+
getFilter: (filter) => {
168+
priceFilter = filter;
169+
},
170+
}),
171+
sort: true,
172+
},
173+
{
174+
dataField: "quantity",
175+
text: "Quantity",
176+
filter: numberFilter({
177+
getFilter: (filter) => {
178+
quantityFilter = filter;
179+
},
180+
}),
181+
sort: true,
182+
},
183+
{
184+
dataField: "created",
185+
text: "Created",
186+
headerStyle: (colum, colIndex) => {
187+
return { width: "220px", textAlign: "center" };
188+
},
189+
formatter: (cell, row) => {
190+
return moment(cell).format("l");
191+
},
192+
filter: dateFilter({
193+
getFilter: (filter) => {
194+
createdFilter = filter;
195+
},
196+
}),
197+
sort: true,
198+
},
199+
{
200+
dataField: "productCodeName",
201+
text: "Product Code",
202+
},
203+
{
204+
dataField: "actions",
205+
text: "",
206+
headerStyle: (colum, colIndex) => {
207+
return { width: "130px", textAlign: "center" };
208+
},
209+
formatter: rowEdit,
210+
},
211+
];
212+
213+
const defaultSorted = [
214+
{
215+
dataField: "name",
216+
order: "desc",
217+
},
218+
];
219+
128220
return (
129221
<>
130222
<br></br>
@@ -134,35 +226,36 @@ const Products = (props) => {
134226
<b>Product Management</b>
135227
<ButtonGroup aria-label="Basic example" className="float-right">
136228
<Button variant="primary">
137-
<FontAwesomeIcon icon={faPlus} /> Create
229+
<FontAwesomeIcon icon={faPlus} /> <b>Create</b>
138230
</Button>
139-
<Button variant="warning" onClick={handleEdit}>
140-
<FontAwesomeIcon icon={faEdit} /> Update
141-
</Button>
142-
<Button variant="danger" onClick={handleDelete}>
143-
<FontAwesomeIcon icon={faTrash} /> Delete
231+
<Button variant="warning" onClick={handleClearFilters}>
232+
<FontAwesomeIcon icon={faEraser} /> <b>Clear Filters</b>{" "}
144233
</Button>
145234
<DropdownButton
146235
as={ButtonGroup}
147236
id="bg-nested-dropdown"
148237
variant="outline-secondary"
149238
title=""
150239
>
151-
<Dropdown.Item eventKey="1" onClick={handleClearFilters}>
152-
Clear filters
240+
<Dropdown.Item eventKey="1">
241+
<FontAwesomeIcon icon={faFileExcel} /> <b>Export</b>{" "}
153242
</Dropdown.Item>
154-
<Dropdown.Item eventKey="2">Export</Dropdown.Item>
155243
</DropdownButton>
156244
</ButtonGroup>
157245
</Card.Header>
158246
<Card.Body>
159-
<RemoteAll
247+
<BootstrapTable
248+
bootstrap4
249+
striped
250+
hover
251+
remote
252+
keyField="id"
160253
data={products}
161-
page={page}
162-
sizePerPage={sizePerPage}
163-
totalSize={totalSize}
254+
columns={columns}
255+
defaultSorted={defaultSorted}
256+
filter={filterFactory()}
257+
pagination={paginationFactory({ page, sizePerPage, totalSize })}
164258
onTableChange={fetchData}
165-
selectRow={selectRow}
166259
/>
167260
</Card.Body>
168261
</Card>
@@ -171,95 +264,4 @@ const Products = (props) => {
171264
);
172265
};
173266

174-
let nameFilter;
175-
let priceFilter;
176-
let quantityFilter;
177-
let createdFilter;
178-
179-
const columns = [
180-
{
181-
dataField: "id",
182-
text: "Product id",
183-
hidden: true,
184-
},
185-
{
186-
dataField: "name",
187-
text: "Product name",
188-
filter: textFilter({
189-
getFilter: (filter) => {
190-
nameFilter = filter;
191-
},
192-
}),
193-
sort: true,
194-
},
195-
{
196-
dataField: "cost",
197-
text: "Product price",
198-
filter: numberFilter({
199-
getFilter: (filter) => {
200-
priceFilter = filter;
201-
},
202-
}),
203-
sort: true,
204-
},
205-
{
206-
dataField: "quantity",
207-
text: "Quantity",
208-
filter: numberFilter({
209-
getFilter: (filter) => {
210-
quantityFilter = filter;
211-
},
212-
}),
213-
sort: true,
214-
},
215-
{
216-
dataField: "created",
217-
text: "Created",
218-
formatter: (cell, row) => {
219-
return moment(cell).format("l");
220-
},
221-
filter: dateFilter({
222-
getFilter: (filter) => {
223-
createdFilter = filter;
224-
},
225-
}),
226-
sort: true,
227-
},
228-
{
229-
dataField: "productCodeName",
230-
text: "Product Code",
231-
},
232-
];
233-
234-
const defaultSorted = [
235-
{
236-
dataField: "name",
237-
order: "desc",
238-
},
239-
];
240-
241-
const RemoteAll = ({
242-
data,
243-
page,
244-
sizePerPage,
245-
onTableChange,
246-
selectRow,
247-
totalSize,
248-
}) => (
249-
<BootstrapTable
250-
bootstrap4
251-
striped
252-
hover
253-
remote
254-
keyField="id"
255-
data={data}
256-
columns={columns}
257-
defaultSorted={defaultSorted}
258-
filter={filterFactory()}
259-
pagination={paginationFactory({ page, sizePerPage, totalSize })}
260-
onTableChange={onTableChange}
261-
selectRow={selectRow}
262-
/>
263-
);
264-
265267
export default Products;

0 commit comments

Comments
 (0)