Commit eb6f7e3a authored by Nawasan Wisitsingkhon's avatar Nawasan Wisitsingkhon

create and show cart in controller;

create: cart list ui;
parent a2278911
import { Request, Response } from "express";
import db from "../models/prismaClient";
const CartController = {
/**
*
* @param {Request} req
* @param {Response} res
*/
async index(req, res) {
try {
let cart = await db.cart.findMany({
where: { user_id: Number(req.user.id) },
});
res.json({ status: 101, message: "fetch success", cart });
} catch (err) {
res.json({ status: 100, message: "error on server" });
}
},
/**
*
* @param {Request} req
* @param {Response} res
*/
async create(req, res) {
try {
const { id } = req.body;
if (!id) throw 200;
let check_cart = await db.cart.findFirst({
where: {
AND: { product_id: Number(id), user_id: Number(req.user.id) },
},
});
if (check_cart) throw 202;
await db.cart.create({
data: {
user_id: Number(req.user.id),
product_id: Number(id),
},
});
await db.$disconnect();
res.json({ status: 201, message: "add to cart success" });
} catch (err) {
if (err === 202)
return res.json({
status: 202,
message: "this product was added",
});
res.json({ status: 200, message: "found some error on server" });
}
},
};
export default CartController;
import express from "express";
import WishlistController from "../controllers/WishlistController";
import CartController from "../controllers/CartController";
const UserRouter = express.Router();
UserRouter.get("/wishlist", WishlistController.index);
UserRouter.post("/wishlist", WishlistController.create);
UserRouter.delete("/wishlist", WishlistController.delete);
UserRouter.get("/cart", CartController.index);
UserRouter.post("/cart", CartController.create);
export default UserRouter;
......@@ -14,7 +14,7 @@ import MenuIcon from "@mui/icons-material/Menu";
import SearchIcon from "@mui/icons-material/Search";
import AccountCircle from "@mui/icons-material/AccountCircle";
import ShoppingCart from "@mui/icons-material/ShoppingCart";
import { UserContext, WishlistContext } from "@/pages/_app";
import { CartContext, UserContext, WishlistContext } from "@/pages/_app";
import Link from "next/link";
import { Favorite } from "@mui/icons-material";
import { Logout, SupervisedUserCircle } from "@mui/icons-material";
......@@ -64,6 +64,7 @@ function Navbar(props) {
const router = useRouter();
const [search, setSearch] = React.useState(router.query?.q ?? "");
const wishlist = useContext(WishlistContext);
const cart = useContext(CartContext)
const user = useContext(UserContext);
const { window } = props;
......@@ -139,7 +140,7 @@ function Navbar(props) {
aria-label="show 4 new mails"
color="inherit"
>
<Badge badgeContent={4} color="error">
<Badge badgeContent={cart.value.length} color="error">
<ShoppingCart />
</Badge>
</IconButton>
......
......@@ -18,18 +18,22 @@ import { UserContext } from "@/pages/_app";
import axios from "axios";
import { headers } from "../../next.config";
export default function ProductCard({ product, isFav, favHandler }) {
const user = useContext(UserContext);
const fav = isFav
export default function ProductCard({
product,
isFav,
favHandler,
cartHandler,
}) {
const fav = isFav;
/**
*
* @param {number} id
* @param {boolean} isRemove
*/
return (
return (
<div
className="p-1 m-1 w-[300px] inline-block bg-white rounded hover:shadow duration-300"
className="p-1 m-1 w-[300px] inline-block bg-white rounded hover:shadow duration-300"
sx={{
m: 1,
px: 1,
......@@ -69,7 +73,7 @@ export default function ProductCard({ product, isFav, favHandler }) {
>
{fav ? <Favorite /> : <FavoriteBorder />}
</Button>
<Button title="เพิ่มลงตระกร้า" color="warning">
<Button title="เพิ่มลงตระกร้า" color="warning" onClick={cartHandler}>
<ShoppingCart />
</Button>
</span>
......
......@@ -14,12 +14,23 @@ import axios from "axios";
export const UserContext = createContext(null);
export const WishlistContext = createContext(null);
export const CartContext = createContext(null);
export default function App({ Component, pageProps }) {
const [user, setUser] = useState({});
const [wishlist, setWishlist] = useState([]);
const [cart, setCart] = useState([]);
const pathname = usePathname();
const fetchCart = async () => {
if (!user.token) return;
let response = await axios.get("/api/u/cart", {
headers: { token: user.token },
});
if (response.data.status === 101) {
setCart(response.data.cart);
}
};
const fetchWishlist = async () => {
if (!user?.token) return;
let response = await axios.get("/api/u/wishlist", {
......@@ -40,30 +51,35 @@ export default function App({ Component, pageProps }) {
}, []);
useEffect(() => {
fetchCart();
fetchWishlist();
}, [user]);
return (
<UserContext.Provider value={{ value: user, set: setUser }}>
<WishlistContext.Provider value={{ value: wishlist, set: setWishlist }}>
{pathname.split("/")[1] === "admin" ? (
<>
{user.rank ? (
<AdminLayout>
<Component {...pageProps} />
</AdminLayout>
) : (
<UserLayout>
<Error />
</UserLayout>
)}
</>
) : (
<UserLayout>
<Component {...pageProps} />
</UserLayout>
)}
</WishlistContext.Provider>
<CartContext.Provider
value={{ value: cart, set: setCart, fetch: fetchCart }}
>
<WishlistContext.Provider value={{ value: wishlist, set: setWishlist }}>
{pathname.split("/")[1] === "admin" ? (
<>
{user.rank ? (
<AdminLayout>
<Component {...pageProps} />
</AdminLayout>
) : (
<UserLayout>
<Error />
</UserLayout>
)}
</>
) : (
<UserLayout>
<Component {...pageProps} />
</UserLayout>
)}
</WishlistContext.Provider>
</CartContext.Provider>
</UserContext.Provider>
);
}
import {
Box,
Button,
Paper,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
} from "@mui/material";
import React, { useContext, useEffect, useState } from "react";
import { CartContext, UserContext, WishlistContext } from "./_app";
import { useRouter } from "next/router";
import axios from "axios";
import { Delete } from "@mui/icons-material";
import { ShoppingCart } from "@mui/icons-material";
import PopupAlert from "@/components/PopupAlert";
import Head from "next/head";
export default function Cart() {
const user = useContext(UserContext);
const wishlist = useContext(WishlistContext);
const cart = useContext(CartContext);
const [products, setProducts] = useState([]);
const [message, setMessage] = useState({ error: false, message: "" });
const router = useRouter();
const [CartProduct, setCartProduct] = useState([]);
const removeFromCart = async (id) => {};
const fetchProduct = async () => {
try {
let product = await axios.get("/api/product");
setProducts(product.data);
} catch (err) {}
};
useEffect(() => {
fetchProduct();
}, []);
useEffect(() => {
setCartProduct(
cart.value.map(
(ct) => products.filter((pd) => pd.id === ct.product_id)[0]
)
);
}, [cart, products]);
return (
<>
<Head>
<title>ตระกร้าสินค้า | OpenShop</title>
</Head>
<Box>
<PopupAlert
open={!!message.message.length}
isError={message.error}
message={message.message}
/>
<Paper sx={{ p: 1, overflowX: "scroll" }}>
{wishlist.value.length > 0 ? (
<Table>
<TableHead>
<TableRow>
{[
"ลำดับ",
"รูปภาพ",
"ชื่อสินค้า",
"รายละเอียด",
"ราคา",
"นำออกจากรายการ",
].map((label, idx) => (
<TableCell key={idx}>{label}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{CartProduct.map(
(pdt, idx) =>
pdt && (
<TableRow key={idx}>
<TableCell>{idx + 1}</TableCell>
<TableCell>
<img
width={100}
src={pdt.image?.length ? pdt.image : "/empty.jpg"}
alt="รูปสินค้า"
/>
</TableCell>
<TableCell>{pdt.name}</TableCell>
<TableCell>
<div className="max-h-10 overflow-scroll">
{pdt.detail}
</div>
</TableCell>
<TableCell>
{pdt.discount > 0 ? (
<Box color={"orangered"}>
<del>${pdt.price}</del> $
{pdt.price - pdt.price * (pdt.discount / 100)}
</Box>
) : (
<Box color="orangered">${pdt.price}</Box>
)}
</TableCell>
<TableCell>
<Button
color="error"
onClick={() => removeFromCart(pdt.id)}
>
<Delete />
</Button>
</TableCell>
</TableRow>
)
)}
</TableBody>
</Table>
) : (
<div className="text-center">รายการว่างเปล่า</div>
)}
</Paper>
</Box>
</>
);
}
......@@ -20,6 +20,25 @@ export default function Home() {
? products.filter((prod) => String(prod.name).includes(router.query.q))
: products.filter((prod) => Number(prod.stock) > 0);
async function onCart(id, isRemove = false) {
if (!user.value?.token) {
setMessage({ message: "คุณยังไม่ได้เข้าสู่ระบบ", error: true });
setTimeout(() => {
setMessage({ message: "", error: true });
}, 2000);
return;
}
if (isRemove) {
} else {
let response = await axios.post(
"/api/u/cart",
{ id },
{ headers: { token: user.value.token } }
);
console.log(response.data);
}
}
async function onWishlist(id, isRemove = false) {
if (!user.value?.token) {
setMessage({ message: "คุณยังไม่ได้เข้าสู่ระบบ", error: true });
......@@ -80,6 +99,7 @@ export default function Home() {
).length
}
product={prod}
cartHandler={() => onCart(prod.id)}
favHandler={() =>
onWishlist(
prod.id,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment