Skip to content
Merged
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
7 changes: 7 additions & 0 deletions .changeset/cart-components-mutations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@godaddy/react": patch
---

Added cart functionality with `useAddToCart` hook and `Cart` component.
Fixed hydration mismatch in `Cart` component.
Removed internal environment references.
1 change: 1 addition & 0 deletions examples/nextjs/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
apiHost={process.env.NEXT_PUBLIC_GODADDY_API_HOST}
storeId={process.env.NEXT_PUBLIC_GODADDY_STORE_ID}
clientId={process.env.NEXT_PUBLIC_GODADDY_CLIENT_ID}
channelId={process.env.NEXT_PUBLIC_GODADDY_CHANNEL_ID}
Link={Link}
appearance={{
variables: { primary: '#ff0000', 'primary-foreground': '#FFFFFF' },
Expand Down
87 changes: 87 additions & 0 deletions examples/nextjs/app/store/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
'use server';

import { createCheckoutSession } from '@godaddy/react/server';
import { redirect } from 'next/navigation';

export async function checkoutWithOrder(orderId: string) {
const session = await createCheckoutSession(
{
returnUrl: `https://godaddy.com`,
successUrl: `https://godaddy.com/success`,
draftOrderId: orderId,
storeId: process.env.NEXT_PUBLIC_GODADDY_STORE_ID || '',
channelId: process.env.NEXT_PUBLIC_GODADDY_CHANNEL_ID || '',
enableShippingAddressCollection: true,
enableBillingAddressCollection: true,
enableTaxCollection: true,
shipping: {
fulfillmentLocationId: 'default-location',
originAddress: {
addressLine1: '1600 Pennsylvania Ave NW',
adminArea1: 'DC',
adminArea3: 'Washington',
countryCode: 'US',
postalCode: '20500',
},
},
taxes: {
originAddress: {
addressLine1: '1600 Pennsylvania Ave NW',
adminArea1: 'DC',
adminArea3: 'Washington',
countryCode: 'US',
postalCode: '20500',
},
},
locations: [
{
id: 'default-location',
isDefault: true,
address: {
addressLine1: '1600 Pennsylvania Ave NW',
adminArea1: 'DC',
adminArea3: 'Washington',
countryCode: 'US',
postalCode: '20500',
},
},
],
paymentMethods: {
card: {
processor: 'godaddy',
checkoutTypes: ['standard'],
},
express: {
processor: 'godaddy',
checkoutTypes: ['express'],
},
paypal: {
processor: 'paypal',
checkoutTypes: ['standard'],
},
offline: {
processor: 'offline',
checkoutTypes: ['standard'],
},
},
},
{
auth: {
clientId: process.env.NEXT_PUBLIC_GODADDY_CLIENT_ID || '',
clientSecret: process.env.GODADDY_CLIENT_SECRET || '',
},
}
);

if (!session) {
throw new Error('Failed to create checkout session');
}

console.log({ session });

if (!session.url) {
throw new Error('No checkout URL returned');
}

redirect(session.url);
}
18 changes: 17 additions & 1 deletion examples/nextjs/app/store/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { Cart } from '@godaddy/react';
import { ShoppingCart } from 'lucide-react';
import { createContext, useContext, useState } from 'react';
import { checkoutWithOrder } from './actions';

interface CartContextType {
openCart: () => void;
Expand All @@ -25,10 +26,20 @@ export default function StoreLayout({
children: React.ReactNode;
}) {
const [isCartOpen, setIsCartOpen] = useState(false);
const [isCheckingOut, setIsCheckingOut] = useState(false);

const openCart = () => setIsCartOpen(true);
const closeCart = () => setIsCartOpen(false);

const handleCheckout = async (orderId: string) => {
setIsCheckingOut(true);
try {
await checkoutWithOrder(orderId);
} catch (_error) {
setIsCheckingOut(false);
}
};

return (
<CartContext.Provider value={{ openCart, closeCart }}>
<section className='relative max-w-6xl mx-auto'>
Expand All @@ -43,7 +54,12 @@ export default function StoreLayout({

{children}

<Cart open={isCartOpen} onOpenChange={setIsCartOpen} />
<Cart
open={isCartOpen}
onOpenChange={setIsCartOpen}
onCheckout={handleCheckout}
isCheckingOut={isCheckingOut}
/>
</section>
</CartContext.Provider>
);
Expand Down
8 changes: 7 additions & 1 deletion examples/nextjs/app/store/product/[productId]/product.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import { ProductDetails } from '@godaddy/react';
import { ArrowLeft } from 'lucide-react';
import Link from 'next/link';
import { useCart } from '../../layout';

export default function Product({ productId }: { productId: string }) {
const { openCart } = useCart();

return (
<div className='container mx-auto'>
<Link
Expand All @@ -14,7 +17,10 @@ export default function Product({ productId }: { productId: string }) {
<ArrowLeft className='h-4 w-4' />
Back to Store
</Link>
<ProductDetails productId={productId} />
<ProductDetails
productId={productId}
onAddToCartSuccess={openCart}
/>
</div>
);
}
8 changes: 7 additions & 1 deletion examples/nextjs/app/store/products.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
'use client';

import { ProductGrid } from '@godaddy/react';
import { useCart } from './layout';

export default function ProductsPage() {
const { openCart } = useCart();

return (
<div className='container mx-auto'>
<ProductGrid getProductHref={sku => `/store/product/${sku}`} />
<ProductGrid
getProductHref={sku => `/store/product/${sku}`}
onAddToCartSuccess={openCart}
/>
</div>
);
}
35 changes: 35 additions & 0 deletions packages/localizations/src/deDe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,39 @@ export const deDe = {
DEPENDENCY_ERROR:
'Wir können Ihre Bestellung derzeit nicht bearbeiten. Bitte warten Sie einen Moment und versuchen Sie es erneut',
},
storefront: {
product: 'Produkt',
sale: 'SALE',
noImage: 'Kein Bild',
noImageAvailable: 'Kein Bild verfügbar',
selectOptions: 'Optionen auswählen',
adding: 'Wird hinzugefügt...',
addToCart: 'In den Warenkorb',
shoppingCart: 'Warenkorb',
failedToLoadCart: 'Warenkorb konnte nicht geladen werden:',
retry: 'Wiederholen',
yourCartIsEmpty: 'Ihr Warenkorb ist leer',
addItemsToGetStarted: 'Fügen Sie Artikel hinzu, um zu beginnen',
errorLoadingProducts: 'Fehler beim Laden der Produkte:',
errorLoadingProduct: 'Fehler beim Laden des Produkts:',
productNotFound: 'Produkt nicht gefunden',
loadingVariantDetails: 'Variantendetails werden geladen...',
combinationNotAvailable:
'Diese Kombination ist nicht verfügbar. Bitte wählen Sie andere Optionen.',
variantsMatch:
'Varianten entsprechen Ihrer Auswahl. Wählen Sie weitere Attribute aus, um die Auswahl einzugrenzen.',
quantity: 'Menge',
addingToCart: 'Wird zum Warenkorb hinzugefügt...',
outOfStock: 'Nicht vorrätig',
viewDetails: 'Details anzeigen',
productType: 'Produkttyp:',
productId: 'Produkt-ID:',
selectedSku: 'Ausgewählte SKU:',
stockStatus: 'Lagerstatus:',
lowStock: 'Geringer Lagerbestand',
inStock: 'Auf Lager',
remove: 'Entfernen',
removing: 'Wird entfernt...',
checkout: 'Zur Kasse',
},
};
35 changes: 35 additions & 0 deletions packages/localizations/src/enIe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,39 @@ export const enIe = {
DEPENDENCY_ERROR:
"We're unable to process your order right now. Please wait a moment and try again",
},
storefront: {
product: 'Product',
sale: 'SALE',
noImage: 'No image',
noImageAvailable: 'No image available',
selectOptions: 'Select Options',
adding: 'Adding...',
addToCart: 'Add to Cart',
shoppingCart: 'Shopping Cart',
failedToLoadCart: 'Failed to load cart:',
retry: 'Retry',
yourCartIsEmpty: 'Your cart is empty',
addItemsToGetStarted: 'Add items to get started',
errorLoadingProducts: 'Error loading products:',
errorLoadingProduct: 'Error loading product:',
productNotFound: 'Product not found',
loadingVariantDetails: 'Loading variant details...',
combinationNotAvailable:
'This combination is not available. Please select different options.',
variantsMatch:
'variants match your selection. Select more attributes to narrow down.',
quantity: 'Quantity',
addingToCart: 'Adding to Cart...',
outOfStock: 'Out of Stock',
viewDetails: 'View Details',
productType: 'Product Type:',
productId: 'Product ID:',
selectedSku: 'Selected SKU:',
stockStatus: 'Stock Status:',
lowStock: 'Low Stock',
inStock: 'In Stock',
remove: 'Remove',
removing: 'Removing...',
checkout: 'Checkout',
},
};
35 changes: 35 additions & 0 deletions packages/localizations/src/enUs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,39 @@ export const enUs = {
DEPENDENCY_ERROR:
"We're unable to process your order right now. Please wait a moment and try again",
},
storefront: {
product: 'Product',
sale: 'SALE',
noImage: 'No image',
noImageAvailable: 'No image available',
selectOptions: 'Select Options',
adding: 'Adding...',
addToCart: 'Add to Cart',
shoppingCart: 'Shopping Cart',
failedToLoadCart: 'Failed to load cart:',
retry: 'Retry',
yourCartIsEmpty: 'Your cart is empty',
addItemsToGetStarted: 'Add items to get started',
errorLoadingProducts: 'Error loading products:',
errorLoadingProduct: 'Error loading product:',
productNotFound: 'Product not found',
loadingVariantDetails: 'Loading variant details...',
combinationNotAvailable:
'This combination is not available. Please select different options.',
variantsMatch:
'variants match your selection. Select more attributes to narrow down.',
quantity: 'Quantity',
addingToCart: 'Adding to Cart...',
outOfStock: 'Out of Stock',
viewDetails: 'View Details',
productType: 'Product Type:',
productId: 'Product ID:',
selectedSku: 'Selected SKU:',
stockStatus: 'Stock Status:',
lowStock: 'Low Stock',
inStock: 'In Stock',
remove: 'Remove',
removing: 'Removing...',
checkout: 'Checkout',
},
};
35 changes: 35 additions & 0 deletions packages/localizations/src/esAr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,4 +331,39 @@ export const esAr = {
DEPENDENCY_ERROR:
'No podemos procesar su pedido en este momento. Espere un momento e inténtelo de nuevo',
},
storefront: {
product: 'Producto',
sale: 'OFERTA',
noImage: 'Sin imagen',
noImageAvailable: 'Sin imagen disponible',
selectOptions: 'Seleccionar opciones',
adding: 'Agregando...',
addToCart: 'Agregar al carrito',
shoppingCart: 'Carrito de compras',
failedToLoadCart: 'Error al cargar el carrito:',
retry: 'Reintentar',
yourCartIsEmpty: 'Tu carrito está vacío',
addItemsToGetStarted: 'Agregá artículos para comenzar',
errorLoadingProducts: 'Error al cargar productos:',
errorLoadingProduct: 'Error al cargar producto:',
productNotFound: 'Producto no encontrado',
loadingVariantDetails: 'Cargando detalles de la variante...',
combinationNotAvailable:
'Esta combinación no está disponible. Por favor seleccioná opciones diferentes.',
variantsMatch:
'variantes coinciden con tu selección. Seleccioná más atributos para reducir las opciones.',
quantity: 'Cantidad',
addingToCart: 'Agregando al carrito...',
outOfStock: 'Agotado',
viewDetails: 'Ver detalles',
productType: 'Tipo de producto:',
productId: 'ID del producto:',
selectedSku: 'SKU seleccionado:',
stockStatus: 'Estado del stock:',
lowStock: 'Stock bajo',
inStock: 'En stock',
remove: 'Eliminar',
removing: 'Eliminando...',
checkout: 'Pagar',
},
};
35 changes: 35 additions & 0 deletions packages/localizations/src/esCl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,4 +333,39 @@ export const esCl = {
DEPENDENCY_ERROR:
'No podemos procesar su pedido en este momento. Espere un momento e inténtelo de nuevo',
},
storefront: {
product: 'Producto',
sale: 'OFERTA',
noImage: 'Sin imagen',
noImageAvailable: 'Sin imagen disponible',
selectOptions: 'Seleccionar opciones',
adding: 'Agregando...',
addToCart: 'Agregar al carrito',
shoppingCart: 'Carrito de compras',
failedToLoadCart: 'Error al cargar el carrito:',
retry: 'Reintentar',
yourCartIsEmpty: 'Tu carrito está vacío',
addItemsToGetStarted: 'Agrega artículos para comenzar',
errorLoadingProducts: 'Error al cargar productos:',
errorLoadingProduct: 'Error al cargar producto:',
productNotFound: 'Producto no encontrado',
loadingVariantDetails: 'Cargando detalles de la variante...',
combinationNotAvailable:
'Esta combinación no está disponible. Por favor selecciona opciones diferentes.',
variantsMatch:
'variantes coinciden con tu selección. Selecciona más atributos para reducir las opciones.',
quantity: 'Cantidad',
addingToCart: 'Agregando al carrito...',
outOfStock: 'Agotado',
viewDetails: 'Ver detalles',
productType: 'Tipo de producto:',
productId: 'ID del producto:',
selectedSku: 'SKU seleccionado:',
stockStatus: 'Estado del stock:',
lowStock: 'Stock bajo',
inStock: 'En stock',
remove: 'Eliminar',
removing: 'Eliminando...',
checkout: 'Pagar',
},
};
Loading