Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Video-40-Admin-Orders
  • Loading branch information
basir committed Jul 13, 2020
commit ab628f0c900855f5e9f11b1420bb6991e30f24b8
34 changes: 21 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,36 +339,44 @@ Feel free to take a look at the course preview and enroll if it is along with yo
1. update ProductListScreen.js
2. handle delete button
3. rerender after deletion
40. Show Categories In Sidebar Menu
1. update ProductListScreen.js
2. handle delete button
3. rerender after deletion
41. Admin Orders
40. Admin Orders
1. create Admin Order menu in header
2. create AdminOrder.js
3. load orders from backend
4. list them in the screen
5. show delete and edit button
6. redirect to order details on edit action
42. Edit Order
41. Edit Order
1. if order is payed show deliver button for admin
2. handle click on deliver button
3. set state to delivered
43. Delete Order
1. update OrderListScreen.js
2. handle delete button
3. rerender after deletion
44. Show Summary Report in Dashboard
42. Show Summary Report in Dashboard
1. create summary section
2. style summary
3. create summary backend
4. create getSummary in api.js
5. load data in dashboard screen
6. show 3 boxes for Users, Orders and Sales
45. Show Chart in Dashboard
43. Show Chart in Dashboard
1. import chartist
2. add chartist css to index.html
3. create linear chart for daily sales
4. create pie chart for product categories
46. Publish heroku
44. Publish heroku
1. publish steps
45. Product Search Bar
1. create search bar in Header.js
2. add style
3. handle submit form
4. edit parse url to get query string
5. update product list api for search keyword
46. Show Categories In Sidebar Menu
1. create aside-open-button in Header.js
2. add event to open aside
3. create Aside.js component
4. Add style aside
5. after render close it on click on close button
6. Use it in index.html
7. Update index.js to render aside 9.
8. call getCategories
9. create getCategories in api.js
28 changes: 27 additions & 1 deletion backend/routers/orderRouter.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import express from 'express';
import expressAsyncHandler from 'express-async-handler';
import { isAuth } from '../utils';
import { isAuth, isAdmin } from '../utils';
import Order from '../models/orderModel';

const orderRouter = express.Router();

orderRouter.get(
'/',
isAuth,
isAdmin,
expressAsyncHandler(async (req, res) => {
const orders = await Order.find({}).populate('user');
res.send(orders);
})
);

orderRouter.get(
'/mine',
isAuth,
Expand Down Expand Up @@ -42,6 +53,21 @@ orderRouter.post(
res.status(201).send({ message: 'New Order Created', order: createdOrder });
})
);
orderRouter.delete(
'/:id',
isAuth,
isAdmin,
expressAsyncHandler(async (req, res) => {
const order = await Order.findById(req.params.id);
if (order) {
const deletedOrder = await order.remove();
res.send({ message: 'Order Deleted', product: deletedOrder });
} else {
res.status(404).send({ message: 'Order Not Found' });
}
})
);

orderRouter.put(
'/:id/pay',
isAuth,
Expand Down
12 changes: 6 additions & 6 deletions backend/routers/productRouter.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import express from 'express';
import expressAysncHandler from 'express-async-handler';
import expressAsyncHandler from 'express-async-handler';
import { isAuth, isAdmin } from '../utils';
import Product from '../models/productModel';

const productRouter = express.Router();
productRouter.get(
'/',
expressAysncHandler(async (req, res) => {
expressAsyncHandler(async (req, res) => {
const products = await Product.find({});
res.send(products);
})
);
productRouter.get(
'/:id',
expressAysncHandler(async (req, res) => {
expressAsyncHandler(async (req, res) => {
const product = await Product.findById(req.params.id);
res.send(product);
})
Expand All @@ -23,7 +23,7 @@ productRouter.post(
'/',
isAuth,
isAdmin,
expressAysncHandler(async (req, res) => {
expressAsyncHandler(async (req, res) => {
const product = new Product({
name: 'sample product',
description: 'sample desc',
Expand All @@ -45,7 +45,7 @@ productRouter.put(
'/:id',
isAuth,
isAdmin,
expressAysncHandler(async (req, res) => {
expressAsyncHandler(async (req, res) => {
const productId = req.params.id;
const product = await Product.findById(productId);
if (product) {
Expand All @@ -71,7 +71,7 @@ productRouter.delete(
'/:id',
isAuth,
isAdmin,
expressAysncHandler(async (req, res) => {
expressAsyncHandler(async (req, res) => {
const product = await Product.findById(req.params.id);
if (product) {
const deletedProduct = await product.remove();
Expand Down
39 changes: 39 additions & 0 deletions frontend/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,45 @@ export const createOrder = async (order) => {
return { error: err.response ? err.response.data.message : err.message };
}
};
export const getOrders = async () => {
try {
const { token } = getUserInfo();
const response = await axios({
url: `${apiUrl}/api/orders`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
});
if (response.statusText !== 'OK') {
throw new Error(response.data.message);
}
return response.data;
} catch (err) {
console.log(err);
return { error: err.response.data.message || err.message };
}
};
export const deleteOrder = async (orderId) => {
try {
const { token } = getUserInfo();
const response = await axios({
url: `${apiUrl}/api/orders/${orderId}`,
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
});
if (response.statusText !== 'OK') {
throw new Error(response.data.message);
}
return response.data;
} catch (err) {
return { error: err.response.data.message || err.message };
}
};
export const getOrder = async (id) => {
try {
const { token } = getUserInfo();
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ const Header = {
name
? `<a href="/#/profile">${name}</a>`
: `<a href="/#/signin">Sign-In</a>`
}

}
<a href="/#/cart">Cart</a>
${isAdmin ? `<a href="/#/dashboard">Dashboard</a>` : ''}
</div>`;
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import OrderScreen from './srceens/OrderScreen';
import DashboardScreen from './srceens/DashboardScreen';
import ProductListScreen from './srceens/ProductListScreen';
import ProductEditScreen from './srceens/ProductEditScreen';
import OrderListScreen from './srceens/OrderListScreen';

const routes = {
'/': HomeScreen,
Expand All @@ -30,6 +31,7 @@ const routes = {
'/placeorder': PlaceOrderScreen,
'/dashboard': DashboardScreen,
'/productlist': ProductListScreen,
'/orderlist': OrderListScreen,
};
const router = async () => {
showLoading();
Expand Down
71 changes: 71 additions & 0 deletions frontend/src/srceens/OrderListScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import DashboardMenu from '../components/DashboardMenu';
import { getOrders, deleteOrder } from '../api';
import { showLoading, hideLoading, rerender, showMessage } from '../utils';

const OrderListScreen = {
after_render: () => {
const deleteButtons = document.getElementsByClassName('delete-button');
Array.from(deleteButtons).forEach((deleteButton) => {
deleteButton.addEventListener('click', async () => {
if (confirm('Are you sure to delete this order?')) {
showLoading();
const data = await deleteOrder(deleteButton.id);
if (data.error) {
showMessage(data.error);
} else {
rerender(OrderListScreen);
}
hideLoading();
}
});
});
},
render: async () => {
const orders = await getOrders();
return `
<div class="dashboard">
${DashboardMenu.render({ selected: 'orders' })}
<div class="dashboard-content">
<h1>Orders</h1>

<div class="order-list">
<table>
<thead>
<tr>
<th>ID</th>
<th>DATE</th>
<th>TOTAL</th>
<th>USER</th>
<th>PAID AT</th>
<th>DELIVERED AT</th>
<th class="tr-action">ACTION</th>
<tr>
</thead>
<tbody>
${orders
.map(
(order) => `
<tr>
<td>${order._id}</td>
<td>${order.createdAt}</td>
<td>${order.totalPrice}</td>
<td>${order.user.name}</td>
<td>${order.paidAt || 'No'}</td>
<td>${order.deliveredAt || 'No'}</td>
<td>
<button id="${order._id}" class="edit-button">Edit</button>
<button id="${order._id}" class="delete-button">Delete</button>
</td>
</tr>
`
)
.join('\n')}
</tbody>
</table>
</div>
</div>
</div>
`;
},
};
export default OrderListScreen;
2 changes: 1 addition & 1 deletion frontend/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ td {
flex: 4 1 80rem;
padding: 1rem;
}

.order-list button,
.product-list button {
font-size: 1.3rem;
padding: 0.5rem;
Expand Down