Changes all .catch(err => console.log(err)); blocks to .catch(err => next(err));
6. Section 20 (File Upload & Download) Changes:
Adds image file upload with multer package with enctype="multipart/form-data" for form
Saves uploaded images to /uploads/images directory
Generates invoice PDF files from orders with pdfkit package
Saves invoice PDFs to /downloads/invoices directory
Requests for previously generated invoices are piped from filesystem
Image files of deleted products are not removed from filesystem because they are needed to generate invoices for past orders that may include deleted products
7. Section 21 (Pagination) Changes:
Adds pagination to '/', '/products', and '/admin/products' routes
8. Section 22 (Async Requests) Changes:
Adds client-side JS to delete product by id and directly removing product from DOM (code included but not used)
9. Section 23 (Stripe Payments) Changes:
Adds payment functionality through Stripe
Creates a new checkout page with Pay with Card button from Stripe
Replaces create-order route with create-checkout route
create-checkout route is placed in app.js to avoid csrf token error
Creates order, submits payment data to Stripe, clears cart, displays orders page
10. Updates 5/2/2019
Add descending createdAt sort order to '/', '/products', and '/admin/products' routes
Add deleted field to Product model with default false
Only products with {deleted: false} are shown
Set to true when product is deleted by user
Product is not deleted from database so it can be used to generate invoices in the future
Throw an error when attempting to view/edit deleted product through URL