175 lines
6.9 KiB
TypeScript
175 lines
6.9 KiB
TypeScript
"use client";
|
|
import { formatPrice } from "@core/app/helpers/Numbers";
|
|
import { useNavigation } from "@core/app/hooks/goto";
|
|
import { PublicServiceView } from "@models/Service.model";
|
|
|
|
import style from "./style.module.css";
|
|
import { getServiceImage } from "@core/helpers/getServiceImage";
|
|
import ServiceRatingSummary from "@components/ServiceRatingSummary/ServiceRatingSummary";
|
|
|
|
export type FindResultsViewMode = "grid" | "card";
|
|
|
|
export interface ProductItemProps {
|
|
product: PublicServiceView;
|
|
width?: number | string;
|
|
viewMode?: FindResultsViewMode;
|
|
dragging?: boolean;
|
|
}
|
|
|
|
export default function ProductItem(props: ProductItemProps) {
|
|
const { width = 220 } = props;
|
|
const { product } = props;
|
|
const { viewMode = "card" } = props;
|
|
const { dragging = false } = props;
|
|
const { goTo } = useNavigation();
|
|
|
|
return (
|
|
<>
|
|
{viewMode === "card" && (
|
|
<div
|
|
key={product.id}
|
|
style={{
|
|
flex: "0 0 auto",
|
|
width: typeof width === "number" ? `${width}px` : width,
|
|
background: "white",
|
|
borderRadius: "10px",
|
|
boxShadow: "0 4px 4px rgba(0, 0, 0, 0.1)",
|
|
overflow: "hidden",
|
|
textAlign: "center",
|
|
padding: "10px",
|
|
border: "solid 1px rgba(0, 0, 0, 0.1)",
|
|
cursor: "pointer",
|
|
position: "relative",
|
|
}}
|
|
onClick={() => {
|
|
if (dragging) return;
|
|
goTo(`/landing/service/${product.id}`);
|
|
}}
|
|
>
|
|
<div className={style.cardImageWrap}>
|
|
<img
|
|
src={getServiceImage(product.image)}
|
|
alt={product.name}
|
|
draggable="false"
|
|
style={{
|
|
width: "100%",
|
|
height: "auto",
|
|
borderRadius: "10px",
|
|
display: "block",
|
|
}}
|
|
/>
|
|
<ServiceRatingSummary
|
|
serviceId={product.id}
|
|
variant="card"
|
|
displayMode="compact"
|
|
showOpinionCount={false}
|
|
enabled={product.showPublicScores !== false}
|
|
/>
|
|
</div>
|
|
<div className={style.cardHeader}>
|
|
<h3 className={style.cardTitle}>{product.name}</h3>
|
|
</div>
|
|
<p style={{ fontSize: "0.9rem", color: "#555" }}>{product.description}</p>
|
|
<span
|
|
style={{
|
|
fontWeight: "bold",
|
|
fontSize: "1.1rem",
|
|
color: "#ff6200",
|
|
}}
|
|
>
|
|
{formatPrice(product.price)}
|
|
</span>
|
|
{product.discountId && (
|
|
<span
|
|
style={{
|
|
backgroundColor: "var(--green-darkestX1)",
|
|
color: "white",
|
|
borderRadius: "5px",
|
|
padding: "2px 5px",
|
|
fontWeight: "bold",
|
|
marginLeft: "10px",
|
|
fontSize: "0.9rem",
|
|
}}
|
|
>
|
|
10% Off
|
|
</span>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{viewMode === "grid" && (
|
|
<div
|
|
key={product.id}
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "row",
|
|
alignItems: "flex-start",
|
|
width: "100%",
|
|
gap: "20px",
|
|
borderBottom: "solid 1px rgba(0, 0, 0, 0.1)",
|
|
cursor: "pointer",
|
|
}}
|
|
onClick={() => {
|
|
goTo(`/landing/service/${product.id}`);
|
|
}}
|
|
>
|
|
<img
|
|
src={getServiceImage(product.image)}
|
|
alt={product.name}
|
|
draggable="false"
|
|
className={style.itemImage}
|
|
style={{
|
|
height: "auto",
|
|
borderRadius: "10px",
|
|
margin: "10px",
|
|
}}
|
|
/>
|
|
<div className={style.itemContent}>
|
|
<div className={style.itemHeader}>
|
|
<h3 className={style.itemTitle}>{product.name}</h3>
|
|
<ServiceRatingSummary
|
|
serviceId={product.id}
|
|
variant="row"
|
|
showOpinionCount={false}
|
|
enabled={product.showPublicScores !== false}
|
|
/>
|
|
</div>
|
|
|
|
<p
|
|
className={style.itemDescription}
|
|
style={{ color: "#555", marginRight: "30px" }}
|
|
>
|
|
{product.description}
|
|
</p>
|
|
<span
|
|
style={{
|
|
fontWeight: "bold",
|
|
fontSize: "1.1rem",
|
|
color: "#ff6200",
|
|
}}
|
|
>
|
|
{formatPrice(product.price)}
|
|
</span>
|
|
{product.discountId && (
|
|
<span
|
|
style={{
|
|
backgroundColor: "var(--green-darkestX1)",
|
|
color: "white",
|
|
borderRadius: "5px",
|
|
padding: "2px 5px",
|
|
fontWeight: "bold",
|
|
maxWidth: "80px",
|
|
textAlign: "center",
|
|
marginLeft: "10px",
|
|
}}
|
|
>
|
|
10% Off
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|