Skip to content

Commit 065e50d

Browse files
WojciechPlodzienAlanJanickikamilkieres09
authored
1.4.2
* fix: [MM2-358] * fix: [MM2-1317] * fix: [MM2-1316] * fix cr issue * fix: [MM2-1273] * fix cr issue * fix cr issue * Merge pull request #214 from mercurjs/fix-ts-issue fix ts issue * fix: [MM2-1392] * fix: [MM2-1333] --------- Co-authored-by: Alan Janicki <[email protected]> Co-authored-by: kamilkieres09 <[email protected]> Co-authored-by: AlanJanicki <[email protected]>
1 parent 615872c commit 065e50d

File tree

21 files changed

+358
-113
lines changed

21 files changed

+358
-113
lines changed

src/app/[locale]/(main)/user/reviews/written/page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getReviews } from "@/lib/data/reviews"
77
export default async function Page() {
88
const user = await retrieveCustomer()
99

10-
const { reviews } = await getReviews()
10+
const reviewsRes = await getReviews()
1111
const orders = await listOrders()
1212

1313
if (!user) return <LoginForm />
@@ -18,7 +18,8 @@ export default async function Page() {
1818
<UserNavigation />
1919
<ReviewsWritten
2020
orders={orders.filter((order) => order.reviews.length)}
21-
reviews={reviews.filter(Boolean)}
21+
reviews={reviewsRes.data?.reviews.filter(Boolean) ?? []}
22+
isError={!reviewsRes.ok}
2223
/>
2324
</div>
2425
</main>

src/app/layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { Funnel_Display } from "next/font/google"
33
import "./globals.css"
44
import { Toaster } from "@medusajs/ui"
55
import Head from "next/head"
6+
import { retrieveCart } from "@/lib/data/cart"
7+
import { Providers } from "./providers"
68

79
const funnelDisplay = Funnel_Display({
810
variable: "--font-funnel-sans",
@@ -41,6 +43,7 @@ export default async function RootLayout({
4143
params: Promise<{ locale: string }>
4244
}>) {
4345
const { locale } = await params
46+
const cart = await retrieveCart()
4447

4548
const ALGOLIA_APP = process.env.NEXT_PUBLIC_ALGOLIA_ID
4649
const htmlLang = locale || "en"
@@ -117,7 +120,7 @@ export default async function RootLayout({
117120
<body
118121
className={`${funnelDisplay.className} antialiased bg-primary text-secondary relative`}
119122
>
120-
{children}
123+
<Providers cart={cart}>{children}</Providers>
121124
<Toaster position="top-right" />
122125
</body>
123126
</html>

src/app/providers.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"use client"
2+
3+
import { CartProvider } from "@/components/providers"
4+
import { Cart } from "@/types/cart"
5+
import type React from "react"
6+
7+
import { PropsWithChildren } from "react"
8+
9+
interface ProvidersProps extends PropsWithChildren {
10+
cart: Cart | null
11+
}
12+
13+
export function Providers({ children, cart }: ProvidersProps) {
14+
return <CartProvider cart={cart}>{children}</CartProvider>
15+
}

src/components/cells/CartDropdown/CartDropdown.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ import { filterValidCartItems } from "@/lib/helpers/filter-valid-cart-items"
1010
import { HttpTypes } from "@medusajs/types"
1111
import { useEffect, useState } from "react"
1212
import { usePathname } from "next/navigation"
13+
import { useCartContext } from "@/components/providers"
1314

1415
const getItemCount = (cart: HttpTypes.StoreCart | null) => {
1516
return cart?.items?.reduce((acc, item) => acc + item.quantity, 0) || 0
1617
}
1718

18-
export const CartDropdown = ({
19-
cart,
20-
}: {
21-
cart: HttpTypes.StoreCart | null
22-
}) => {
19+
export const CartDropdown = () => {
20+
const { cart } = useCartContext()
2321
const [open, setOpen] = useState(false)
2422

2523
const previousItemCount = usePrevious(getItemCount(cart))
@@ -96,7 +94,7 @@ export const CartDropdown = ({
9694
<div className="overflow-y-scroll max-h-[360px] no-scrollbar">
9795
{validItems.map((item) => (
9896
<CartDropdownItem
99-
key={item.id}
97+
key={`${item.product_id}-${item.variant_id}`}
10098
item={item}
10199
currency_code={cart?.currency_code || "eur"}
102100
/>

src/components/cells/ProductDetailsHeader/ProductDetailsHeader.tsx

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { SellerProps } from "@/types/seller"
1212
import { WishlistButton } from "../WishlistButton/WishlistButton"
1313
import { Wishlist } from "@/types/wishlist"
1414
import { toast } from "@/lib/helpers/toast"
15+
import { useCartContext } from "@/components/providers"
1516

1617
const optionsAsKeymap = (
1718
variantOptions: HttpTypes.StoreProductVariant["options"]
@@ -40,6 +41,7 @@ export const ProductDetailsHeader = ({
4041
user: HttpTypes.StoreCustomer | null
4142
wishlist?: Wishlist[]
4243
}) => {
44+
const { onAddToCart, cart } = useCartContext()
4345
const [isAdding, setIsAdding] = useState(false)
4446
const { allSearchParams } = useGetAllSearchParams()
4547

@@ -74,13 +76,42 @@ export const ProductDetailsHeader = ({
7476
variantId,
7577
})
7678

79+
const variantStock =
80+
product.variants?.find(({ id }) => id === variantId)?.inventory_quantity ||
81+
0
82+
83+
const variantHasPrice = !!product.variants?.find(({ id }) => id === variantId)
84+
?.calculated_price
85+
86+
const isVariantStockMaxLimitReached =
87+
(cart?.items?.find((item) => item.variant_id === variantId)?.quantity ??
88+
0) >= variantStock
89+
7790
// add the selected variant to the cart
7891
const handleAddToCart = async () => {
7992
if (!variantId || !hasAnyPrice) return null
8093

8194
setIsAdding(true)
8295

96+
const subtotal = +(variantPrice?.calculated_price_without_tax_number || 0)
97+
const total = +(variantPrice?.calculated_price_number || 0)
98+
99+
const storeCartLineItem = {
100+
thumbnail: product.thumbnail || "",
101+
product_title: product.title,
102+
quantity: 1,
103+
subtotal,
104+
total,
105+
tax_total: total - subtotal,
106+
variant_id: variantId,
107+
product_id: product.id,
108+
variant: product.variants?.find(({ id }) => id === variantId),
109+
}
110+
83111
try {
112+
if (!isVariantStockMaxLimitReached) {
113+
onAddToCart(storeCartLineItem, variantPrice?.currency_code || "eur")
114+
}
84115
await addToCart({
85116
variantId: variantId,
86117
quantity: 1,
@@ -96,15 +127,6 @@ export const ProductDetailsHeader = ({
96127
}
97128
}
98129

99-
const variantStock =
100-
product.variants?.find(({ id }) => id === variantId)?.inventory_quantity ||
101-
0
102-
103-
const variantHasPrice = product.variants?.find(({ id }) => id === variantId)
104-
?.calculated_price
105-
? true
106-
: false
107-
108130
return (
109131
<div className="border rounded-sm p-5">
110132
<div className="flex justify-between">
@@ -149,7 +171,7 @@ export const ProductDetailsHeader = ({
149171
{/* Add to Cart */}
150172
<Button
151173
onClick={handleAddToCart}
152-
disabled={isAdding || !variantStock || !variantHasPrice || !hasAnyPrice}
174+
disabled={!variantStock || !variantHasPrice || !hasAnyPrice}
153175
loading={isAdding}
154176
className="w-full uppercase mb-4 py-3 flex justify-center"
155177
size="large"
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"use client"
2+
import { Button } from "@/components/atoms"
3+
import { cn } from "@/lib/utils"
4+
import { useRouter } from "next/navigation"
5+
6+
interface RefreshButtonProps {
7+
label: string | React.ReactNode
8+
className?: string
9+
}
10+
11+
export function RefreshButton({ label, className }: RefreshButtonProps) {
12+
const router = useRouter()
13+
14+
return (
15+
<Button
16+
onClick={() => router.refresh()}
17+
className={cn("max-w-fit", className)}
18+
>
19+
{label}
20+
</Button>
21+
)
22+
}

src/components/molecules/SellerReview/SellerReview.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ export const SellerReview = ({ review }: { review: SingleProductReview }) => {
1818
</p>
1919
</div>
2020
<div className="w-5/6">
21-
<p className="text-md">{review.customer_note}</p>
21+
<p className="text-md whitespace-pre-line break-words">
22+
{review.customer_note}
23+
</p>
2224
{review.seller_note && (
2325
<div className="mt-4 flex gap-4 relative">
2426
<Divider orientation="vertical" className="h-auto" />

src/components/organisms/Header/Header.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { CartDropdown, MobileNavbar, Navbar } from "@/components/cells"
55
import { HeartIcon, MessageIcon } from "@/icons"
66
import { listCategories } from "@/lib/data/categories"
77
import { PARENT_CATEGORIES } from "@/const"
8-
import { retrieveCart } from "@/lib/data/cart"
98
import { UserDropdown } from "@/components/cells/UserDropdown/UserDropdown"
109
import { retrieveCustomer } from "@/lib/data/customer"
1110
import { getUserWishlists } from "@/lib/data/wishlist"
@@ -18,7 +17,6 @@ import { MessageButton } from "@/components/molecules/MessageButton/MessageButto
1817
import { SellNowButton } from "@/components/cells/SellNowButton/SellNowButton"
1918

2019
export const Header = async () => {
21-
const cart = await retrieveCart().catch(() => null)
2220
const user = await retrieveCustomer()
2321
let wishlist: Wishlist[] = []
2422
if (user) {
@@ -75,7 +73,7 @@ export const Header = async () => {
7573
</LocalizedClientLink>
7674
)}
7775

78-
<CartDropdown cart={cart} />
76+
<CartDropdown />
7977
</div>
8078
</div>
8179
<Navbar categories={categories} />

src/components/organisms/Reviews/OrderCard.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ export const OrderCard = ({
5252
</Button>
5353
</div>
5454
) : (
55-
<div className="h-full -mt-2">
55+
<div className="h-full -mt-2 max-w-full">
5656
<p className="text-sm text-secondary">
5757
{format(order.reviews[0].created_at, "MMM dd, yyyy")}
5858
</p>
5959
<StarRating rate={order.reviews[0].rating} starSize={12} />
60-
<p className="label-md mt-2">{order.reviews[0].customer_note}</p>
60+
<p className="label-md mt-2 whitespace-pre-line break-words">
61+
{order.reviews[0].customer_note}
62+
</p>
6163
</div>
6264
)}
6365
</div>

src/components/organisms/Reviews/ReviewsWritten.tsx

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,56 @@ import { Order, Review } from "@/lib/data/reviews"
55
import { isEmpty } from "lodash"
66
import { usePathname } from "next/navigation"
77
import { OrderCard } from "./OrderCard"
8+
import { RefreshButton } from "@/components/cells/RefreshButton/RefreshButton"
89

910
export const ReviewsWritten = ({
1011
reviews,
1112
orders,
13+
isError,
1214
}: {
1315
reviews: Review[]
1416
orders: Order[]
17+
isError: boolean
1518
}) => {
1619
const pathname = usePathname()
1720

21+
function renderReviews() {
22+
if (isError) {
23+
return (
24+
<div className="flex flex-col gap-2">
25+
<p className="text-negative">
26+
Something went wrong while fetching reviews
27+
</p>
28+
<RefreshButton label="Refresh" />
29+
</div>
30+
)
31+
}
32+
33+
if (isEmpty(reviews)) {
34+
return (
35+
<Card>
36+
<div className="text-center py-6">
37+
<h3 className="heading-lg text-primary uppercase">
38+
No written reviews
39+
</h3>
40+
<p className="text-lg text-secondary mt-2">
41+
You haven&apos;t written any reviews yet. Once you write a review,
42+
it will appear here.
43+
</p>
44+
</div>
45+
</Card>
46+
)
47+
}
48+
49+
return (
50+
<div className="space-y-2">
51+
{orders.map((order) => (
52+
<OrderCard key={order.id} order={order} />
53+
))}
54+
</div>
55+
)
56+
}
57+
1858
return (
1959
<div className="md:col-span-3 space-y-8">
2060
<h1 className="heading-md uppercase">Reviews</h1>
@@ -30,25 +70,7 @@ export const ReviewsWritten = ({
3070
</NavigationItem>
3171
))}
3272
</div>
33-
{isEmpty(reviews) ? (
34-
<Card>
35-
<div className="text-center py-6">
36-
<h3 className="heading-lg text-primary uppercase">
37-
No written reviews
38-
</h3>
39-
<p className="text-lg text-secondary mt-2">
40-
You haven&apos;t written any reviews yet. Once you write a review,
41-
it will appear here.
42-
</p>
43-
</div>
44-
</Card>
45-
) : (
46-
<div className="space-y-2">
47-
{orders.map((order) => (
48-
<OrderCard key={order.id} order={order} />
49-
))}
50-
</div>
51-
)}
73+
{renderReviews()}
5274
</div>
5375
)
5476
}

0 commit comments

Comments
 (0)