this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 86 lines 2.7 kB view raw
1import { connection } from 'next/server'; 2import type { Product } from '#/types/product'; 3import { Ping } from '#/components/ping'; 4import { ProductEstimatedArrival } from '#/components/product-estimated-arrival'; 5import { ProductLowStockWarning } from '#/components/product-low-stock-warning'; 6import { ProductPrice } from '#/components/product-price'; 7import { ProductSplitPayments } from '#/components/product-split-payments'; 8import { ProductUsedPrice } from '#/components/product-used-price'; 9import { dinero, type DineroSnapshot } from 'dinero.js'; 10import { Suspense } from 'react'; 11import { AddToCart } from '#/components/add-to-cart'; 12import { delayShippingEstimate, withDelay } from '#/lib/delay'; 13import { cookies } from 'next/headers'; 14import { getProduct } from '#/lib/products'; 15 16async function AddToCartFromCookies() { 17 // Tell Next.js to render dynamically at runtime instead of build-time 18 await connection(); 19 20 // Get the cart count from the users cookies and pass it to the client 21 // AddToCart component 22 const cartCount = Number(cookies().get('_cart_count')?.value || '0'); 23 return <AddToCart initialCartCount={cartCount} />; 24} 25 26function LoadingDots() { 27 return ( 28 <div className="text-sm"> 29 <span className="space-x-0.5"> 30 <span className="inline-flex animate-[loading_1.4s_ease-in-out_infinite] rounded-full"> 31 &bull; 32 </span> 33 <span className="inline-flex animate-[loading_1.4s_ease-in-out_0.2s_infinite] rounded-full"> 34 &bull; 35 </span> 36 <span className="inline-flex animate-[loading_1.4s_ease-in-out_0.4s_infinite] rounded-full"> 37 &bull; 38 </span> 39 </span> 40 </div> 41 ); 42} 43 44async function UserSpecificDetails({ productId }: { productId: string }) { 45 const data = await withDelay( 46 getProduct({ id: productId }), 47 delayShippingEstimate, 48 ); 49 50 const product = (await data.json()) as Product; 51 52 const price = dinero(product.price as DineroSnapshot<number>); 53 54 return ( 55 <> 56 <ProductSplitPayments price={price} /> 57 {product.usedPrice ? ( 58 <ProductUsedPrice usedPrice={product.usedPrice} /> 59 ) : null} 60 <ProductEstimatedArrival leadTime={product.leadTime} hasDeliveryTime /> 61 {product.stock <= 1 ? ( 62 <ProductLowStockWarning stock={product.stock} /> 63 ) : null} 64 </> 65 ); 66} 67 68export function Pricing({ product }: { product: Product }) { 69 const price = dinero(product.price as DineroSnapshot<number>); 70 71 return ( 72 <div className="space-y-4 rounded-lg bg-gray-900 p-3"> 73 <ProductPrice price={price} discount={product.discount} /> 74 75 <Ping /> 76 77 <Suspense fallback={<LoadingDots />}> 78 <UserSpecificDetails productId={product.id} /> 79 </Suspense> 80 81 <Suspense fallback={<AddToCart initialCartCount={0} />}> 82 <AddToCartFromCookies /> 83 </Suspense> 84 </div> 85 ); 86}