Skip to content

Commit ebdca21

Browse files
authored
Merge pull request #23 from Tr-andreson/feature/RouteOptimization
Performance/route optimization
2 parents 17ab529 + 7455c82 commit ebdca21

7 files changed

Lines changed: 3163 additions & 259 deletions

File tree

app/cart/page.tsx

Lines changed: 7 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
1-
"use client";
21

32
import {
4-
CustomButton,
5-
QuantityInput,
6-
QuantityInputCart,
7-
SectionTitle,
3+
SectionTitle
84
} from "@/components";
9-
import Image from "next/image";
10-
import React from "react";
11-
import { FaCheck, FaClock, FaCircleQuestion, FaXmark } from "react-icons/fa6";
12-
import { useProductStore } from "../_zustand/store";
13-
import Link from "next/link";
14-
import toast from "react-hot-toast";
5+
import { Loader } from "@/components/Loader";
6+
import { CartModule } from "@/components/modules/cart";
7+
import { Suspense } from "react";
158

169
const CartPage = () => {
17-
const { products, removeFromCart, calculateTotals, total } =
18-
useProductStore();
19-
20-
const handleRemoveItem = (id: string) => {
21-
removeFromCart(id);
22-
calculateTotals();
23-
toast.success("Product removed from the cart");
24-
};
25-
2610
return (
2711
<div className="bg-white">
2812
<SectionTitle title="Cart Page" path="Home | Cart" />
@@ -31,166 +15,9 @@ const CartPage = () => {
3115
<h1 className="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
3216
Shopping Cart
3317
</h1>
34-
<form className="mt-12 lg:grid lg:grid-cols-12 lg:items-start lg:gap-x-12 xl:gap-x-16">
35-
<section aria-labelledby="cart-heading" className="lg:col-span-7">
36-
<h2 id="cart-heading" className="sr-only">
37-
Items in your shopping cart
38-
</h2>
39-
40-
<ul
41-
role="list"
42-
className="divide-y divide-gray-200 border-b border-t border-gray-200"
43-
>
44-
{products.map((product) => (
45-
<li key={product.id} className="flex py-6 sm:py-10">
46-
<div className="flex-shrink-0">
47-
<Image
48-
width={192}
49-
height={192}
50-
src={product?.image ? `/${product.image}` : "/product_placeholder.jpg"}
51-
alt="laptop image"
52-
className="h-24 w-24 rounded-md object-cover object-center sm:h-48 sm:w-48"
53-
/>
54-
</div>
55-
56-
<div className="ml-4 flex flex-1 flex-col justify-between sm:ml-6">
57-
<div className="relative pr-9 sm:grid sm:grid-cols-2 sm:gap-x-6 sm:pr-0">
58-
<div>
59-
<div className="flex justify-between">
60-
<h3 className="text-sm">
61-
<Link
62-
href={`#`}
63-
className="font-medium text-gray-700 hover:text-gray-800"
64-
>
65-
{product.title}
66-
</Link>
67-
</h3>
68-
</div>
69-
{/* <div className="mt-1 flex text-sm">
70-
<p className="text-gray-500">{product.color}</p>
71-
{product.size ? (
72-
<p className="ml-4 border-l border-gray-200 pl-4 text-gray-500">{product.size}</p>
73-
) : null}
74-
</div> */}
75-
<p className="mt-1 text-sm font-medium text-gray-900">
76-
${product.price}
77-
</p>
78-
</div>
79-
80-
<div className="mt-4 sm:mt-0 sm:pr-9">
81-
<QuantityInputCart product={product} />
82-
<div className="absolute right-0 top-0">
83-
<button
84-
onClick={() => handleRemoveItem(product.id)}
85-
type="button"
86-
className="-m-2 inline-flex p-2 text-gray-400 hover:text-gray-500"
87-
>
88-
<span className="sr-only">Remove</span>
89-
<FaXmark className="h-5 w-5" aria-hidden="true" />
90-
</button>
91-
</div>
92-
</div>
93-
</div>
94-
95-
<p className="mt-4 flex space-x-2 text-sm text-gray-700">
96-
{1 ? (
97-
<FaCheck
98-
className="h-5 w-5 flex-shrink-0 text-green-500"
99-
aria-hidden="true"
100-
/>
101-
) : (
102-
<FaClock
103-
className="h-5 w-5 flex-shrink-0 text-gray-300"
104-
aria-hidden="true"
105-
/>
106-
)}
107-
108-
<span>{1 ? "In stock" : `Ships in 3 days`}</span>
109-
</p>
110-
</div>
111-
</li>
112-
))}
113-
</ul>
114-
</section>
115-
116-
{/* Order summary */}
117-
<section
118-
aria-labelledby="summary-heading"
119-
className="mt-16 rounded-lg bg-gray-50 px-4 py-6 sm:p-6 lg:col-span-5 lg:mt-0 lg:p-8"
120-
>
121-
<h2
122-
id="summary-heading"
123-
className="text-lg font-medium text-gray-900"
124-
>
125-
Order summary
126-
</h2>
127-
128-
<dl className="mt-6 space-y-4">
129-
<div className="flex items-center justify-between">
130-
<dt className="text-sm text-gray-600">Subtotal</dt>
131-
<dd className="text-sm font-medium text-gray-900">
132-
${total}
133-
</dd>
134-
</div>
135-
<div className="flex items-center justify-between border-t border-gray-200 pt-4">
136-
<dt className="flex items-center text-sm text-gray-600">
137-
<span>Shipping estimate</span>
138-
<a
139-
href="#"
140-
className="ml-2 flex-shrink-0 text-gray-400 hover:text-gray-500"
141-
>
142-
<span className="sr-only">
143-
Learn more about how shipping is calculated
144-
</span>
145-
<FaCircleQuestion
146-
className="h-5 w-5"
147-
aria-hidden="true"
148-
/>
149-
</a>
150-
</dt>
151-
<dd className="text-sm font-medium text-gray-900">$5.00</dd>
152-
</div>
153-
<div className="flex items-center justify-between border-t border-gray-200 pt-4">
154-
<dt className="flex text-sm text-gray-600">
155-
<span>Tax estimate</span>
156-
<a
157-
href="#"
158-
className="ml-2 flex-shrink-0 text-gray-400 hover:text-gray-500"
159-
>
160-
<span className="sr-only">
161-
Learn more about how tax is calculated
162-
</span>
163-
<FaCircleQuestion
164-
className="h-5 w-5"
165-
aria-hidden="true"
166-
/>
167-
</a>
168-
</dt>
169-
<dd className="text-sm font-medium text-gray-900">
170-
${total / 5}
171-
</dd>
172-
</div>
173-
<div className="flex items-center justify-between border-t border-gray-200 pt-4">
174-
<dt className="text-base font-medium text-gray-900">
175-
Order total
176-
</dt>
177-
<dd className="text-base font-medium text-gray-900">
178-
${total === 0 ? 0 : Math.round(total + total / 5 + 5)}
179-
</dd>
180-
</div>
181-
</dl>
182-
{products.length > 0 && (
183-
<div className="mt-6">
184-
<Link
185-
href="/checkout"
186-
className="block flex justify-center items-center w-full uppercase bg-white px-4 py-3 text-base border border-black border-gray-300 font-bold text-blue-600 shadow-sm hover:bg-black hover:bg-gray-100 focus:outline-none focus:ring-2"
187-
>
188-
<span>Checkout</span>
189-
</Link>
190-
</div>
191-
)}
192-
</section>
193-
</form>
18+
<Suspense fallback={<Loader />}>
19+
<CartModule />
20+
</Suspense>
19421
</div>
19522
</div>
19623
</div>

app/error.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
"use client"
3+
4+
import { AiOutlineWarning } from "react-icons/ai"
5+
6+
const GlobalError = ({ error }: { error: Error }) => {
7+
8+
return (
9+
<div className="flex flex-col items-center justify-center h-[300px] text-center p-6 rounded-2xl bg-red-50 border border-red-200 shadow-sm">
10+
<AiOutlineWarning className="w-12 h-12 text-red-500 mb-4" />
11+
<h3 className="text-2xl font-semibold text-red-700">Something went wrong</h3>
12+
<p className="text-red-500 mt-3 max-w-md">{error.message}</p>
13+
</div>
14+
)
15+
}
16+
17+
export default GlobalError

app/wishlist/page.tsx

Lines changed: 17 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,27 @@
1-
"use client";
2-
import { SectionTitle, WishItem } from "@/components";
3-
import React, { useEffect, useState } from "react";
4-
import { useWishlistStore } from "../_zustand/wishlistStore";
5-
import { nanoid } from "nanoid";
6-
import { useSession } from "next-auth/react";
1+
import { SectionTitle } from "@/components";
2+
import { Loader } from "@/components/Loader";
3+
import dynamic from "next/dynamic";
4+
import React, { Suspense } from "react";
75

6+
import { WishlistModule } from "@/components/modules/wishlist"; //slow
87

8+
// const DynamicWishlistModule = dynamic(
9+
// () =>
10+
// (async () => {
11+
// const mod = await import("@/components/modules/wishlist");
12+
// return mod.WishlistModule
13+
// })(),
14+
// { ssr: false }
15+
// );
916

10-
const WishlistPage = () => {
11-
const { data: session, status } = useSession();
12-
const {wishlist, setWishlist}= useWishlistStore();
13-
14-
const getWishlistByUserId = async (id: string) => {
15-
const response = await fetch(`http://localhost:3001/api/wishlist/${id}`, {
16-
cache: "no-store",
17-
});
18-
const wishlist = await response.json();
19-
20-
const productArray: {
21-
id: string;
22-
title: string;
23-
price: number;
24-
image: string;
25-
slug:string
26-
stockAvailabillity: number;
27-
}[] = [];
28-
29-
wishlist.map((item:any) => productArray.push({id: item?.product?.id, title: item?.product?.title, price: item?.product?.price, image: item?.product?.mainImage, slug: item?.product?.slug, stockAvailabillity: item?.product?.inStock}));
30-
31-
setWishlist(productArray);
32-
};
3317

34-
const getUserByEmail = async () => {
35-
if (session?.user?.email) {
36-
fetch(`http://localhost:3001/api/users/email/${session?.user?.email}`, {
37-
cache: "no-store",
38-
})
39-
.then((response) => response.json())
40-
.then((data) => {
41-
getWishlistByUserId(data?.id);
42-
});
43-
}
44-
};
45-
46-
useEffect(() => {
47-
getUserByEmail();
48-
}, [session?.user?.email, wishlist.length]);
18+
const WishlistPage = () => {
4919
return (
5020
<div className="bg-white">
5121
<SectionTitle title="Wishlist" path="Home | Wishlist" />
52-
{wishlist && wishlist.length === 0 ? (
53-
<h3 className="text-center text-4xl py-10 text-black max-lg:text-3xl max-sm:text-2xl max-sm:pt-5 max-[400px]:text-xl">
54-
No items found in the wishlist
55-
</h3>
56-
) : (
57-
<div className="max-w-screen-2xl mx-auto">
58-
<div className="overflow-x-auto">
59-
<table className="table text-center">
60-
<thead>
61-
<tr>
62-
<th></th>
63-
<th className="text-accent-content">Image</th>
64-
<th className="text-accent-content">Name</th>
65-
<th className="text-accent-content">Stock Status</th>
66-
<th className="text-accent-content">Action</th>
67-
</tr>
68-
</thead>
69-
<tbody>
70-
{wishlist &&
71-
wishlist?.map((item) => (
72-
<WishItem
73-
id={item?.id}
74-
title={item?.title}
75-
price={item?.price}
76-
image={item?.image}
77-
slug={item?.slug}
78-
stockAvailabillity={item?.stockAvailabillity}
79-
key={nanoid()}
80-
/>
81-
))}
82-
</tbody>
83-
</table>
84-
</div>
85-
</div>
86-
)}
22+
<Suspense fallback={<Loader />}>
23+
<WishlistModule />
24+
</Suspense>
8725
</div>
8826
);
8927
};

0 commit comments

Comments
 (0)