Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Diego31-10/TableOrderApp/llms.txt

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

Table mode activates automatically when a customer is within the restaurant’s geofence radius (50 meters by default). Customers scan a QR code at their table to start an ordering session with a menu tailored to their table type.

How it works

1

GPS geofencing detection

The app uses the Haversine formula to calculate the distance between the user’s GPS coordinates and the restaurant location:
src/components/location/ContextSwitcher.tsx
function calculateDistance(c1: Coordinates, c2: Coordinates): number {
  const R = 6_371_000;
  const φ1 = (c1.latitude * Math.PI) / 180;
  const φ2 = (c2.latitude * Math.PI) / 180;
  const Δφ = ((c2.latitude - c1.latitude) * Math.PI) / 180;
  const Δλ = ((c2.longitude - c1.longitude) * Math.PI) / 180;
  const a =
    Math.sin(Δφ / 2) ** 2 +
    Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) ** 2;
  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
}
If the distance is ≤ 50 meters, the app switches to SCANNER mode.
2

QR code scanning

The camera activates and displays a branded overlay with an animated scan frame. See QR Scanner for details.
3

Table session initialization

When a valid QR code is scanned, the app:
  • Validates the table ID against the TABLES_DATA registry (src/lib/core/mockData.ts:9)
  • Stores the active table in useTableStore (src/stores/useTableStore.ts:10)
  • Triggers multimodal feedback (haptic + sound)
  • Navigates to the menu screen
4

Contextual menu display

The menu filters products based on the table’s menuType. See Contextual Menus for details.

Table types

Tables are configured with a menuType property that determines which products are visible:
Tables with menuType: 'FULL' display all product categories:
  • Food
  • Snacks
  • Drinks
  • Desserts
{
  id: 'TABLE_HALL_05',
  displayName: 'Salon 05',
  menuType: 'FULL',
  status: 'FREE',
  specialEvent: 'NONE'
}

State management

Table mode uses three Zustand stores:

Location store

src/stores/useLocationStore.ts
interface LocationState {
  appMode: AppMode;              // 'CHECKING' | 'SCANNER' | 'DELIVERY'
  userLocation: Coordinates | null;
  restaurantLocation: Coordinates | null;
  setAppMode: (mode: AppMode) => void;
}
When geofencing detects the user is within range (src/components/location/ContextSwitcher.tsx:84):
if (distanceMeters <= Config.restaurant.geofenceRadiusMeters) {
  setAppMode('SCANNER');
  setServiceType('TABLE');
}

Table store

Manages the active table session:
const setTable = useTableStore((s) => s.setTable);
setTable(data); // stores TableData object

Cart store

Handles orders and birthday discounts:
src/stores/useCartStore.ts
setBirthdayMode: (active: boolean, discount = 0) => {
  const { items } = get();
  set({
    isBirthdayMode: active,
    discount: active ? discount : 0,
    total: calcTotal(items, active ? discount : 0),
  });
}
The birthday discount is applied immediately when the table is scanned (src/lib/modules/menu/useMenuLogic.ts:22), not at checkout.

QR code format

Table QR codes must match the format TABLE_* to be recognized. Test codes:
QR CodeTableMenu TypeSpecial Event
TABLE_BAR_01Barra 01Drinks onlyNone
TABLE_HALL_05Salon 05Full menuNone
TABLE_BDAY_99Mesa EspecialFull menuBirthday (15% off)
QR codes that don’t exist in TABLES_DATA trigger an error toast and reset the scanner to idle state (src/components/scanner/CameraScanner.tsx:60).

Session lifecycle

The session is cleared after successful payment (src/app/(checkout)/payment.tsx:252):
clearSession();  // resets useTableStore
resetLocation(); // resets useLocationStore
resetCart();     // resets useCartStore

QR Scanner

Camera-based QR code scanning with idempotency guards

Contextual Menus

Dynamic menu filtering by table type

Payments

Checkout flow and payment processing

Delivery Mode

Alternative mode for customers outside the geofence

Build docs developers (and LLMs) love