Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import LocalizedClientLink from "@/components/molecules/LocalizedLink/LocalizedLink"
import { CollapseIcon } from "@/icons"
import { SellerInfo } from "@/components/molecules"
import { SellerProps } from "@/types/seller"

Expand All @@ -8,13 +6,10 @@ export const ProductDetailsSeller = ({ seller }: { seller?: SellerProps }) => {

return (
<div className="border rounded-sm">
<div className="p-4">
<LocalizedClientLink href={`/sellers/${seller.handle}`}>
<div>
<div className="flex justify-between">
<SellerInfo seller={seller} />
<CollapseIcon className="-rotate-90" />
<SellerInfo seller={seller} showArrow bottomBorder />
</div>
</LocalizedClientLink>
</div>
</div>
)
Expand Down
6 changes: 4 additions & 2 deletions src/components/cells/SellerAvatar/SellerAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@ export const SellerAvatar = ({
alt={alt}
width={size}
height={size}
style={{ width: size, height: size }}
className="shrink-0"
style={{ maxWidth: size, maxHeight: size }}
/>
) : (
<Image
src="/images/placeholder.svg"
alt={alt}
className="opacity-30 w-8 h-8"
className="opacity-30 w-8 h-8 shrink-0"
width={32}
height={32}
style={{ maxWidth: 32, maxHeight: 32 }}
/>
)
}
59 changes: 38 additions & 21 deletions src/components/molecules/SellerInfo/SellerInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { StarRating } from "@/components/atoms"
import { SellerAvatar } from "@/components/cells/SellerAvatar/SellerAvatar"
import { SellerProps } from "@/types/seller"
import { SellerReview } from "../SellerReview/SellerReview"
import LocalizedClientLink from "../LocalizedLink/LocalizedLink"
import { SellerInfoHeader } from "../SellerInfoHeader/SellerInfoHeader"

export const SellerInfo = ({
seller,
header = false,
showArrow = false,
bottomBorder = false,
}: {
seller: SellerProps
header?: boolean
showArrow?: boolean
bottomBorder?: boolean
}) => {
const { photo, name, reviews } = seller

Expand All @@ -24,26 +28,39 @@ export const SellerInfo = ({
: 0

return (
<div className="flex gap-4 w-full">
<div className="relative h-12 w-12 overflow-hidden rounded-sm">
<SellerAvatar photo={photo} size={56} alt={name} />
</div>
<div className="w-[90%]">
<h3 className="heading-sm text-primary">{name}</h3>
<div className="flex items-center gap-2 border-b pb-4">
<StarRating starSize={16} rate={rating || 0} />
<span className="text-md text-secondary">{reviewCount} reviews</span>
<div className="flex flex-col w-full">
{showArrow ? (
<LocalizedClientLink href={`/sellers/${seller.handle}`} aria-label={`View ${name} seller`}>
<SellerInfoHeader
photo={photo}
name={name}
rating={rating}
reviewCount={reviewCount}
showArrow={showArrow}
bottomBorder={bottomBorder}
/>
</LocalizedClientLink>
) : (
<SellerInfoHeader
photo={photo}
name={name}
rating={rating}
reviewCount={reviewCount}
showArrow={showArrow}
bottomBorder={bottomBorder}
/>
)}
{!header && (
<div className="flex flex-col gap-5 p-4">
<h3 className="heading-sm uppercase">Seller reviews</h3>
{reviews
?.filter((rev) => rev !== null)
.slice(-3)
.map((review) => (
<SellerReview key={review.id} review={review} />
))}
</div>
<div className="mt-4">
{!header &&
reviews
?.filter((rev) => rev !== null)
.slice(-3)
.map((review) => (
<SellerReview key={review.id} review={review} />
))}
</div>
</div>
)}
</div>
)
}
39 changes: 39 additions & 0 deletions src/components/molecules/SellerInfoHeader/SellerInfoHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { StarRating } from "@/components/atoms"
import { SellerAvatar } from "@/components/cells/SellerAvatar/SellerAvatar"
import { CollapseIcon } from "@/icons"
import clsx from "clsx"

export const SellerInfoHeader = ({
photo,
name,
rating,
reviewCount,
showArrow,
bottomBorder = false,
}: {
photo: string
name: string
rating: number
reviewCount: number
showArrow: boolean
bottomBorder?: boolean
}) => (
<div
className={clsx(
"flex gap-4 w-full p-5 items-center",
bottomBorder && "border-b"
)}
>
<div className="rounded-sm">
<SellerAvatar photo={photo} size={56} alt={name} />
</div>
<div className="flex flex-col gap-1">
<h3 className="heading-sm text-primary">{name}</h3>
<div className="flex items-center gap-2">
<StarRating starSize={14} rate={rating || 0} />
<span className="label-md text-secondary">{reviewCount} reviews</span>
</div>
</div>
{showArrow && <CollapseIcon className="ml-auto -rotate-90" />}
</div>
)
55 changes: 34 additions & 21 deletions src/components/molecules/SellerReview/SellerReview.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,53 @@
import { StarRating } from "@/components/atoms"
import { SingleProductReview } from "@/types/product"
import { Divider } from "@medusajs/ui"
import clsx from "clsx"
import { formatDistanceToNow } from "date-fns"

export const SellerReview = ({ review }: { review: SingleProductReview }) => {
return (
<div className="mb-4 border-b pb-4 flex gap-4">
<div className="mb-4 w-1/6 items-center">
<p className="label-md text-secondary mb-2 truncate">
{review.customer.first_name} {review.customer.last_name}
</p>
<StarRating starSize={12} rate={Number(review.rating.toFixed(1))} />
<p className="text-sm text-secondary mt-2">
{formatDistanceToNow(new Date(review.created_at), {
addSuffix: true,
})}
</p>
<div className={clsx("gap-2 flex flex-col justify-center", review.seller_note && "border-b pb-4 mb-4")}>
<div className="items-center flex gap-3">
<StarRating starSize={14} rate={Number(review.rating.toFixed(1))} />
<div className="flex gap-2 items-center">
<p className="label-md text-primary truncate">
{review.customer.first_name} {review.customer.last_name}
</p>
<Divider
orientation="vertical"
className="h-[10px] border-disabled"
/>
<p className="label-md text-secondary">
{formatDistanceToNow(new Date(review.created_at), {
addSuffix: true,
})}
</p>
</div>
</div>
<div className="w-5/6">
<p className="text-md whitespace-pre-line break-words">
<p className="text-md whitespace-pre-line break-words text-primary">
{review.customer_note}
</p>
{review.seller_note && (
<div className="mt-4 flex gap-4 relative">
<div className="mt-4 flex gap-4">
<Divider orientation="vertical" className="h-auto" />
<div>
<p className="label-md text-primary">
Reply from {review.seller.name}{" "}
<span className="text-secondary">
|{" "}
<div className="flex flex-col gap-2">
<div className="flex gap-2 items-center">
<p className="label-md text-primary">
Reply from {review.seller.name}
</p>
<Divider
orientation="vertical"
className="h-[10px] border-disabled"
/>

<p className="label-md text-secondary">
{formatDistanceToNow(new Date(review.updated_at), {
addSuffix: true,
})}
</span>
</p>
<p className="label-sm mt-2">{review.seller_note}</p>
</p>
</div>
<p className="label-sm">{review.seller_note}</p>
</div>
</div>
)}
Expand Down
2 changes: 2 additions & 0 deletions src/components/molecules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ProductCarouselIndicator } from "./ProductCarouselIndicator/ProductCaro
import { Modal } from "./Modal/Modal"
import { ReportListingForm } from "./ReportListingForm/ReportListingForm"
import { SellerInfo } from "./SellerInfo/SellerInfo"
import { SellerInfoHeader } from "./SellerInfoHeader/SellerInfoHeader"
import { TabsList } from "./TabsList/TabsList"
import { TabsContent } from "./TabsContent/TabsContent"
import { SellerScore } from "./SellerScore/SellerScore"
Expand Down Expand Up @@ -49,6 +50,7 @@ export {
Modal,
ReportListingForm,
SellerInfo,
SellerInfoHeader,
TabsList,
TabsContent,
SellerScore,
Expand Down
7 changes: 6 additions & 1 deletion src/components/organisms/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const Chat = ({
product,
subject,
order_id,
variant = "tonal",
buttonSize = "small",
}: {
user: HttpTypes.StoreCustomer | null
seller: SellerProps
Expand All @@ -26,6 +28,8 @@ export const Chat = ({
product?: HttpTypes.StoreProduct
subject?: string
order_id?: string
variant?: "tonal" | "filled"
buttonSize?: "small" | "large"
}) => {
const [modal, setModal] = useState(false)

Expand All @@ -36,9 +40,10 @@ export const Chat = ({
return (
<>
<Button
variant="tonal"
variant={variant}
onClick={() => setModal(true)}
className={buttonClassNames}
size={buttonSize}
>
{icon ? <MessageIcon size={20} /> : "Write to seller"}
</Button>
Expand Down
4 changes: 2 additions & 2 deletions src/components/organisms/SellerFooter/SellerFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useState } from "react"
export const SellerFooter = ({ seller }: { seller: SellerProps }) => {
const [openModal, setOpenModal] = useState(false)
return (
<div className="flex justify-between items-center flex-col lg:flex-row">
<div className="flex justify-between items-center flex-col lg:flex-row p-5">
<div className="flex gap-2 lg:gap-4 items-center label-sm lg:label-md text-secondary mb-4 lg:mb-0 justify-between w-full lg:justify-start lg:w-auto">
{/* {seller.verified && (
<div className="flex items-center gap-2">
Expand All @@ -29,7 +29,7 @@ export const SellerFooter = ({ seller }: { seller: SellerProps }) => {
className="uppercase"
onClick={() => setOpenModal(true)}
>
Report
Report Seller
</Button>
{openModal && (
<Modal heading="Report seller" onClose={() => setOpenModal(false)}>
Expand Down
36 changes: 25 additions & 11 deletions src/components/organisms/SellerHeading/SellerHeading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SellerInfo } from "@/components/molecules"
import { SellerProps } from "@/types/seller"
import { Chat } from "../Chat/Chat"
import { HttpTypes } from "@medusajs/types"
import { Button } from "@medusajs/ui"

export const SellerHeading = ({
seller,
Expand All @@ -13,18 +14,31 @@ export const SellerHeading = ({
user: HttpTypes.StoreCustomer | null
}) => {
return (
<div className="flex justify-between flex-col lg:flex-row">
<SellerInfo header seller={seller} />
{user && (
<div className="flex items-center gap-2 mt-4 lg:mt-0">
<Chat
user={user}
seller={seller}
icon
buttonClassNames="w-10 h-10 flex justify-center items-center p-0"
/>
<div className="border-b">
<div className="flex flex-col md:flex-row justify-between">
<div>
<SellerInfo header={header} seller={seller} />
</div>
)}
{user && (
<div className="flex gap-2 md:mt-0 p-5 md:ml-auto">
<Chat
user={user}
seller={seller}
buttonClassNames="uppercase h-10"
variant="filled"
buttonSize="small"
/>
</div>
)}
</div>
<div className="px-5 pb-5">
<p
dangerouslySetInnerHTML={{
__html: seller.description,
}}
className="label-md"
/>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,8 @@ export const SellerPageHeader = ({
user: HttpTypes.StoreCustomer | null
}) => {
return (
<div className="border rounded-sm p-4">
<div className="border rounded-sm">
<SellerHeading header seller={seller} user={user} />
<p
dangerouslySetInnerHTML={{
__html: seller.description,
}}
className="label-md my-5"
/>
<SellerFooter seller={seller} />
</div>
)
Expand Down