Update react editor
This commit is contained in:
@@ -181,7 +181,7 @@ const CartDrawer: React.FC = () => {
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
disabled={loading}
|
||||
className="text-muted-foreground hover:text-foreground"
|
||||
className="h-auto w-auto p-2 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<X size={18} />
|
||||
</Button>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useRouteHandle } from '@/lib/resolve-route';
|
||||
import { ChevronDown, SlidersHorizontal } from 'lucide-react';
|
||||
import type { ShopifyCollection } from '@reacteditor/field-shopify';
|
||||
import {
|
||||
@@ -358,10 +358,8 @@ function buildProductFilters(active: ActiveFilters): ProductFilter[] {
|
||||
|
||||
export function CollectionView(props: CollectionProps) {
|
||||
const { collection: selected, showDescription, showCoverImage, customCoverImage, columns, limit, defaultSort } = props;
|
||||
const params = useParams();
|
||||
const paramHandle =
|
||||
typeof params?.handle === 'string' ? params.handle : undefined;
|
||||
const handle = selected?.handle ?? paramHandle ?? '';
|
||||
const routeHandle = useRouteHandle();
|
||||
const handle = selected?.handle ?? routeHandle ?? '';
|
||||
|
||||
const [sort, setSort] = useState<CollectionSortKey>(defaultSort);
|
||||
const [reverse, setReverse] = useState(false);
|
||||
@@ -425,7 +423,7 @@ export function CollectionView(props: CollectionProps) {
|
||||
const description = collection?.description ?? (selected as any)?.description;
|
||||
const collectionImage = customCoverImage || collection?.image?.url;
|
||||
|
||||
if (!selected && !paramHandle) {
|
||||
if (!selected && !routeHandle) {
|
||||
return (
|
||||
<section className="bg-background pb-24 pt-12 md:pt-20">
|
||||
<Container>
|
||||
@@ -463,7 +461,7 @@ export function CollectionView(props: CollectionProps) {
|
||||
Collection
|
||||
</p>
|
||||
<Typography variant="h1">
|
||||
{collection?.title ?? (selected as any)?.title ?? paramHandle}
|
||||
{collection?.title ?? (selected as any)?.title ?? routeHandle}
|
||||
</Typography>
|
||||
{showDescription === 'yes' && description ? (
|
||||
<Typography variant="subtitle1" className="mt-4 max-w-2xl">
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useProduct, type Product } from '@/hooks/use-shopify-products';
|
||||
import { useRouteHandle } from '@/lib/resolve-route';
|
||||
import { useShopifyCart } from '@/hooks/use-shopify-cart';
|
||||
import ProductDetailGallery from './product-detail-gallery';
|
||||
import ProductDetailInfo from './product-detail-info';
|
||||
import ProductRecommendations from './product-recommendations';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Alert, AlertTitle, AlertDescription } from '@/components/ui/alert';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
@@ -44,7 +44,8 @@ interface ProductDetailProps {
|
||||
}
|
||||
|
||||
const ProductDetail: React.FC<ProductDetailProps> = ({ handle: handleProp }) => {
|
||||
const handle = handleProp || '';
|
||||
const routeHandle = useRouteHandle();
|
||||
const handle = handleProp || routeHandle || '';
|
||||
const { addItem, openCart } = useShopifyCart();
|
||||
|
||||
const { product, loading, error } = useProduct(handle);
|
||||
@@ -197,8 +198,6 @@ const ProductDetail: React.FC<ProductDetailProps> = ({ handle: handleProp }) =>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ProductRecommendations productId={product.id} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useRouteHandle } from "@/lib/resolve-route";
|
||||
import type { ShopifyProduct } from "@reacteditor/field-shopify";
|
||||
import { useProduct } from "@/hooks/use-shopify-products";
|
||||
import { useShopifyCart } from "@/hooks/use-shopify-cart";
|
||||
@@ -14,10 +14,8 @@ export type ProductDetailsProps = {
|
||||
};
|
||||
|
||||
export function ProductDetailsView({ product: selected }: ProductDetailsProps) {
|
||||
const params = useParams();
|
||||
const paramHandle =
|
||||
typeof params?.handle === "string" ? params.handle : undefined;
|
||||
const handle = selected?.handle ?? paramHandle ?? null;
|
||||
const routeHandle = useRouteHandle();
|
||||
const handle = selected?.handle ?? routeHandle ?? null;
|
||||
const { product, loading } = useProduct(handle);
|
||||
const cart = useShopifyCart();
|
||||
const [activeImage, setActiveImage] = useState(0);
|
||||
|
||||
25
components/commerce/product-recommendations.editor.tsx
Normal file
25
components/commerce/product-recommendations.editor.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentConfig } from "@reacteditor/core";
|
||||
import { LayoutGrid } from "lucide-react";
|
||||
import {
|
||||
ProductRecommendationsView,
|
||||
type ProductRecommendationsProps,
|
||||
} from "@/components/commerce/product-recommendations";
|
||||
|
||||
const productRecommendationsEditor: ComponentConfig<ProductRecommendationsProps> = {
|
||||
label: "Product recommendations",
|
||||
icon: <LayoutGrid size={16} />,
|
||||
category: "commerce",
|
||||
defaultProps: {
|
||||
product: null,
|
||||
heading: "You Might Also Like",
|
||||
limit: 4,
|
||||
},
|
||||
fields: {
|
||||
product: { label: "Source product", type: "shopifyProduct" } as any,
|
||||
heading: { label: "Heading", type: "text", contentEditable: true },
|
||||
limit: { label: "Limit", type: "number", min: 2, max: 8 },
|
||||
},
|
||||
render: (props) => <ProductRecommendationsView {...props} />,
|
||||
};
|
||||
|
||||
export default productRecommendationsEditor;
|
||||
@@ -1,15 +1,31 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { useProductRecommendations } from '@/hooks/use-shopify-products';
|
||||
import ProductCard from '../product-card';
|
||||
import type { ShopifyProduct } from '@reacteditor/field-shopify';
|
||||
import {
|
||||
useProduct,
|
||||
useProductRecommendations,
|
||||
} from '@/hooks/use-shopify-products';
|
||||
import { useRouteHandle } from '@/lib/resolve-route';
|
||||
import { ProductCard } from './product-card';
|
||||
|
||||
interface ProductRecommendationsProps {
|
||||
productId: string;
|
||||
}
|
||||
export type ProductRecommendationsProps = {
|
||||
product: ShopifyProduct | null;
|
||||
heading: string;
|
||||
limit: number;
|
||||
};
|
||||
|
||||
const ProductRecommendations: React.FC<ProductRecommendationsProps> = ({ productId }) => {
|
||||
const { recommendations, loading, error } = useProductRecommendations(productId);
|
||||
export function ProductRecommendationsView({
|
||||
product: selected,
|
||||
heading,
|
||||
limit,
|
||||
}: ProductRecommendationsProps) {
|
||||
const routeHandle = useRouteHandle();
|
||||
const handle = selected?.handle ?? routeHandle ?? null;
|
||||
const { product } = useProduct(handle);
|
||||
const { recommendations, loading, error } = useProductRecommendations(
|
||||
product?.id ?? null,
|
||||
);
|
||||
|
||||
// Don't show section if we're not loading and have no recommendations
|
||||
if (!loading && (!recommendations || recommendations.length === 0)) {
|
||||
@@ -20,12 +36,12 @@ const ProductRecommendations: React.FC<ProductRecommendationsProps> = ({ product
|
||||
<div className="bg-muted py-16">
|
||||
<div className="container mx-auto px-4">
|
||||
<h2 className="text-4xl font-bold text-center mb-12 text-foreground font-heading">
|
||||
You Might Also Like
|
||||
{heading}
|
||||
</h2>
|
||||
|
||||
{loading ? (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
|
||||
{Array.from({ length: 4 }).map((_, index) => (
|
||||
{Array.from({ length: limit }).map((_, index) => (
|
||||
<div key={index} className="bg-card rounded-lg shadow-md overflow-hidden animate-pulse">
|
||||
<div className="aspect-square bg-muted"></div>
|
||||
<div className="p-6">
|
||||
@@ -43,7 +59,7 @@ const ProductRecommendations: React.FC<ProductRecommendationsProps> = ({ product
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8">
|
||||
{recommendations.slice(0, 4).map((recommendedProduct) => (
|
||||
{recommendations.slice(0, limit).map((recommendedProduct) => (
|
||||
<ProductCard
|
||||
key={recommendedProduct.id}
|
||||
product={recommendedProduct}
|
||||
@@ -54,6 +70,6 @@ const ProductRecommendations: React.FC<ProductRecommendationsProps> = ({ product
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default ProductRecommendations;
|
||||
export default ProductRecommendationsView;
|
||||
Reference in New Issue
Block a user