JSPM

  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q101695F
  • License MIT

Pre-built UI components for OMS e-commerce sites

Package Exports

  • @instockng/storefront-ui
  • @instockng/storefront-ui/fetchers
  • @instockng/storefront-ui/styles.css

Readme

@instockng/storefront-ui

Pre-built React UI components for building e-commerce storefronts with the OMS (Order Management System) API. Built with React, TypeScript, Tailwind CSS, and shadcn/ui.

Installation

npm install @instockng/storefront-ui @tanstack/react-query lucide-react

Quick Start

  • Drop-in Components - Fully functional UI out of the box
  • Fully Typed - TypeScript support with auto-generated API types
  • Customizable - Override styles with className props
  • Theme Support - Pass custom colors, fonts, and styling
  • Responsive - Mobile-first design
  • Accessible - Built with accessibility in mind

Installation

npm install @instockng/storefront-ui
# or
pnpm add @instockng/storefront-ui

Peer Dependencies

npm install react react-dom @tanstack/react-query lucide-react

Usage

Setup

Add storefront-ui to your Tailwind config's content array:

// tailwind.config.ts
export default {
  content: [
    './app/**/*.{js,ts,jsx,tsx}',
    './node_modules/@instockng/storefront-ui/src/**/*.{js,ts,jsx,tsx}', // Add this
  ],
  // ... rest of your config
}

Option B: If your project doesn't use Tailwind CSS

Import the pre-built CSS file:

// app/layout.tsx or _app.tsx
import '@instockng/storefront-ui/styles.css';

Providers

Wrap your app with providers:

import { ApiClientProvider } from '@instockng/storefront-ui';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <ApiClientProvider baseURL="https://api.yoursite.com">
        <YourApp />
      </ApiClientProvider>
    </QueryClientProvider>
  );
}

Quick Start Examples

ProductGrid - Product Catalog

import { ProductGrid } from '@instockng/storefront-ui';

function ProductCatalog() {
  return (
    <ProductGrid
      brandId="your-brand-uuid"
      onAddToCart={(variantId, quantity) => {
        console.log('Adding to cart:', variantId, quantity);
      }}
      columns={3}
      showStock={true}
    />
  );
}

ShoppingCart - Cart Sidebar with Integrated Checkout

The ShoppingCart component now includes an integrated Checkout modal - no need to handle onCheckout unless you want custom behavior!

import { ShoppingCart, CartProvider } from '@instockng/storefront-ui';

function MyApp() {
  const [isCartOpen, setIsCartOpen] = useState(false);

  return (
    <CartProvider cartId="cart-uuid">
      {/* Your app content */}
      <button onClick={() => setIsCartOpen(true)}>Open Cart</button>

      {/* Cart with integrated checkout - no onCheckout needed! */}
      <ShoppingCart
        isOpen={isCartOpen}
        onClose={() => setIsCartOpen(false)}
        onOrderSuccess={(orderId) => {
          console.log('Order placed:', orderId);
          // Optionally navigate or show success message
        }}
        showDiscountCode={true}
      />
    </CartProvider>
  );
}

Custom Checkout Handler (Optional)

If you need custom behavior, you can still pass onCheckout:

<ShoppingCart
  isOpen={isCartOpen}
  onClose={() => setIsCartOpen(false)}
  onCheckout={() => navigate('/custom-checkout')} // Custom behavior
  showDiscountCode={true}
/>

CheckoutSummary - Checkout Page

import { CheckoutSummary } from '@instockng/storefront-ui';

function CheckoutPage() {
  const navigate = useNavigate();

  return (
    <CheckoutSummary
      cartId="cart-uuid"
      brandId="brand-uuid"
      onSuccess={(orderId, token) => {
        navigate(`/order-confirmation/${orderId}/${token}`);
      }}
      cartSummary={{
        subtotal: 100.00,
        discountAmount: 10.00,
        discountCode: 'SAVE10',
        deliveryFee: 5.00,
        total: 95.00
      }}
    />
  );
}

OrderConfirmation - Confirmation Page

import { OrderConfirmation } from '@instockng/storefront-ui';

function OrderPage() {
  const { orderId, token } = useParams();

  return (
    <OrderConfirmation
      orderId={orderId}
      token={token}
      onConfirm={(orderNumber) => {
        console.log('Order confirmed:', orderNumber);
      }}
    />
  );
}

Customization

<OrderConfirmation
  orderId={orderId}
  token={token}
  // Custom styling
  className="bg-white"
  headerClassName="text-brand-blue"
  buttonClassName="bg-brand-primary hover:bg-brand-primary-dark"
  cardClassName="shadow-lg border-brand-gray"

  // Custom locale & currency
  currency="USD"
  locale="en-US"

  // Custom WhatsApp support
  whatsappHelpLink="https://wa.me/1234567890"
  whatsappHelpNumber="+1 (234) 567-890"

  // Callbacks
  onConfirm={(orderNumber) => {
    // Track analytics
    analytics.track('Order Confirmed', { orderNumber });
    // Redirect
    router.push('/thank-you');
  }}
  onError={(error) => {
    // Show toast notification
    toast.error('Failed to confirm order');
  }}
/>

Available Components

Product Components

  • ProductGrid - Grid of products with add to cart, filtering, and customization
  • ProductCard - Individual product with variants, images, stock status, and quantity selector

Cart Components

  • ShoppingCart - Full cart display with items, discount codes, and checkout button
  • CartItem - Individual cart item with quantity controls and remove button
  • DiscountCodeInput - Standalone discount code input with validation

Checkout Components

  • CheckoutSummary - Complete checkout form with customer info, delivery, and payment
  • DeliveryZoneSelector - Delivery zone dropdown grouped by state

Order Components

  • OrderConfirmation - Order confirmation page for confirming prospect orders

Theming

All components accept className props for custom styling:

<OrderConfirmation
  className="font-custom"              // Root container
  headerClassName="text-brand-color"   // Header section
  buttonClassName="bg-brand-primary"   // Buttons
  cardClassName="border-brand-gray"    // Card components
/>

Using with Tailwind

The components are built with Tailwind CSS. Make sure your tailwind.config.js includes the package:

module.exports = {
  content: [
    './src/**/*.{js,ts,jsx,tsx}',
    './node_modules/@instockng/storefront-ui/**/*.{js,ts,jsx,tsx}',
  ],
  // ... your config
}

API Hooks

All @oms/api-client hooks are re-exported for convenience:

import {
  useGetOrder,
  useConfirmOrder,
  useGetProducts,
  useGetCart,
  useCheckout,
  // ... all other hooks
} from '@instockng/storefront-ui';

UI Primitives

Access underlying UI components for custom layouts:

import {
  Button,
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  Badge,
} from '@instockng/storefront-ui';

Utilities

Helper functions for formatting:

import {
  formatCurrency,
  formatDate,
  formatDateTime,
  getStatusColor,
  cn, // Tailwind class merger
} from '@instockng/storefront-ui';

// Usage
formatCurrency(1999.99, 'USD', 'en-US'); // "$1,999.99"
formatDate('2024-01-15'); // "January 15, 2024"
formatDateTime('2024-01-15T10:30:00'); // "January 15, 2024 at 10:30 AM"
getStatusColor('shipped'); // "bg-blue-100 text-blue-800"
cn('base-class', { 'conditional': true }); // Merges Tailwind classes

TypeScript

All components are fully typed with TypeScript:

import type { OrderConfirmationProps } from '@instockng/storefront-ui';

const config: OrderConfirmationProps = {
  orderId: '123',
  token: 'abc',
  // TypeScript will autocomplete and validate all props
};

Examples

Simple Usage

import { OrderConfirmation } from '@instockng/storefront-ui';

export default function OrderPage({ orderId, token }) {
  return <OrderConfirmation orderId={orderId} token={token} />;
}

With Custom Brand Colors

import { OrderConfirmation } from '@instockng/storefront-ui';

export default function BrandedOrderPage({ orderId, token }) {
  return (
    <OrderConfirmation
      orderId={orderId}
      token={token}
      className="bg-gray-50 font-inter"
      headerClassName="text-purple-600"
      buttonClassName="bg-purple-600 hover:bg-purple-700"
      cardClassName="border-purple-200"
      currency="USD"
      locale="en-US"
    />
  );
}

With Analytics Tracking

import { OrderConfirmation } from '@instockng/storefront-ui';
import { analytics } from './analytics';

export default function TrackedOrderPage({ orderId, token }) {
  return (
    <OrderConfirmation
      orderId={orderId}
      token={token}
      onConfirm={(orderNumber) => {
        analytics.track('Order Confirmed', {
          orderNumber,
          orderId,
        });

        // Redirect to thank you page
        window.location.href = '/thank-you';
      }}
      onError={(error) => {
        analytics.track('Order Confirmation Failed', {
          error: error.message,
          orderId,
        });
      }}
    />
  );
}

Development

This package is part of the OMS monorepo. When the backend API changes:

# Regenerate types
cd packages/types
pnpm run generate

# The storefront-ui will automatically pick up new types

License

ISC