Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dlampatricio/florale/llms.txt

Use this file to discover all available pages before exploring further.

Floralé manages all client-side shopping cart state through a Zustand store defined in lib/cart-store.ts. The store tracks which items have been added, exposes drawer open/close controls, and is automatically persisted to localStorage so customers don’t lose their cart between page visits. A companion store in lib/toast-store.ts handles ephemeral notification messages that auto-dismiss after 2.5 seconds.
Both useCartStore and useToastStore are client-only hooks. Any component that calls them must include the 'use client' directive at the top of the file. Do not call these hooks inside Server Components or Route Handlers.

useCartStore

The primary store for cart management. Created with zustand/middleware’s persist wrapper so that cart items survive full-page navigations and browser refreshes.
import { useCartStore } from '@/lib/cart-store';

Persistence

SettingValue
Storage keyflorale-cart
Storage mediumlocalStorage
Persisted fieldsitems only
Not persistedisDrawerOpen (always resets to false on load)

CartItem (store-internal interface)

The CartItem used inside the store is different from the CartItem exported by types/index.ts. The store version includes an extra note field for personalisation messages.
export interface CartItem {
  productId: string;  // UUID of the product
  quantity: number;   // How many units the customer wants
  note: string;       // Personalisation note — always a string, defaults to '' on new items
}
The CartItem in types/index.ts does not have a note field. The extended interface is exported directly from lib/cart-store.ts for use in components that need to display or edit the note.

State fields

items
CartItem[]
The current contents of the cart. Each entry holds a productId, a quantity, and a note. Persisted to localStorage.
isDrawerOpen
boolean
Whether the cart slide-over drawer is currently visible. Defaults to false on every page load (not persisted).

Actions

addItem

Adds a product to the cart. If the product is already present its quantity is incremented; otherwise a new CartItem is inserted with an empty note.
addItem(productId: string, quantity?: number): void
productId
string
required
The UUID of the product to add.
quantity
number
The number of units to add. Defaults to 1. When the item already exists in the cart, this value is added to the existing quantity rather than replacing it.
const { addItem } = useCartStore();

// Add a single unit (quantity defaults to 1)
addItem('product-uuid-here');

removeItem

Removes a product from the cart entirely, regardless of quantity.
removeItem(productId: string): void
productId
string
required
The UUID of the product to remove. If the ID is not found in the cart the call is a no-op.
const { removeItem } = useCartStore();

removeItem('product-uuid-here');

updateQuantity

Sets the quantity of a cart item to an explicit value. If the new quantity is 0 or negative the item is automatically removed from the cart.
updateQuantity(productId: string, quantity: number): void
productId
string
required
The UUID of the product whose quantity should be updated.
quantity
number
required
The new quantity. Passing 0 or any negative number removes the item from the cart entirely.
const { updateQuantity } = useCartStore();

function handleQuantityChange(productId: string, value: string) {
  const quantity = parseInt(value, 10);
  // Passing 0 will remove the item automatically
  updateQuantity(productId, isNaN(quantity) ? 1 : quantity);
}

updateNote

Attaches or replaces the personalisation note on an existing cart item. Useful for gift messages or special instructions.
updateNote(productId: string, note: string): void
productId
string
required
The UUID of the product whose note should be updated.
note
string
required
The new note text. Pass an empty string to clear the note. If the product is not in the cart the call is a no-op.
const { updateNote } = useCartStore();

function handleNoteChange(productId: string, note: string) {
  updateNote(productId, note);
}

clearCart

Removes all items from the cart at once. Drawer state is unaffected.
clearCart(): void
const { clearCart, closeDrawer } = useCartStore();

async function handleCheckout() {
  await submitOrder();
  clearCart();
  closeDrawer();
}

openDrawer / closeDrawer / toggleDrawer

Controls for the cart slide-over drawer. These only affect the isDrawerOpen flag — they do not modify cart items.
openDrawer(): void
closeDrawer(): void
toggleDrawer(): void
'use client';

import { useCartStore } from '@/lib/cart-store';

export function CartButton() {
  const { toggleDrawer, items } = useCartStore();

  return (
    <button onClick={toggleDrawer} aria-label="Open cart">
      🛒 {items.length}
    </button>
  );
}

Common patterns

'use client';

import { useCartStore } from '@/lib/cart-store';

export function CartSummary() {
  const items = useCartStore((state) => state.items);

  const totalQuantity = items.reduce((acc, item) => acc + item.quantity, 0);

  return <span>{totalQuantity} item{totalQuantity !== 1 ? 's' : ''}</span>;
}

useToastStore

A lightweight Zustand store for ephemeral notification banners. Toasts are automatically removed after 2 500 ms — no manual cleanup needed in the vast majority of cases.
import { useToastStore } from '@/lib/toast-store';

State fields

toasts
Toast[]
The list of currently visible toast notifications. Each entry has an id (a crypto.randomUUID() string) and a message string.

addToast

Adds a new toast and schedules its automatic removal after 2 500 ms.
addToast(message: string): void
message
string
required
The text to display inside the toast notification. Emojis are encouraged 🌸.

removeToast

Manually removes a toast before its automatic timeout fires. Useful for dismissible toasts with a close button.
removeToast(id: string): void
id
string
required
The id of the toast to remove. IDs are generated internally by crypto.randomUUID() when addToast is called.

Usage

'use client';

import { useToastStore } from '@/lib/toast-store';

export function ToastContainer() {
  const { toasts, removeToast } = useToastStore();

  return (
    <div aria-live="polite">
      {toasts.map((toast) => (
        <div key={toast.id} role="status">
          {toast.message}
          <button onClick={() => removeToast(toast.id)}></button>
        </div>
      ))}
    </div>
  );
}
You don’t need to call removeToast after addToast unless you’re building a dismissible UI. The store’s internal setTimeout cleans up the toast at 2 500 ms automatically.

Build docs developers (and LLMs) love