Back to Archive
Case Study ยท 2024FeaturedBeta

Southside Flow

Southside Flow

A comprehensive restaurant management dashboard with real-time order tracking and dynamic menu customization.

Southside Flow
Order #1234 Status Updated (Live)

A robust Next.js application providing a comprehensive administration dashboard for restaurant operations. It features real-time order management, dynamic menu configuration, staff access control, and sales analytics, all powered by Supabase.

Problem Visual
The Problem

The Chaos of Manual Restaurant Management.

Traditional restaurant operations often face significant inefficiencies due to manual order tracking, static menus requiring constant updates, and a lack of real-time sales data. This often leads to slower service, inventory discrepancies, and difficulty in making data-driven business decisions. Furthermore, managing staff access and roles can be cumbersome, impacting both operational security and workflow efficiency.

Solution Visual
The Solution

Real-time Clarity.
Effortless Operations.

Southside Flow addresses these challenges with a modern, full-stack Next.js application, leveraging Supabase for a robust backend. It provides a real-time admin dashboard for efficient order processing, dynamic menu management with image uploads and category reordering, and detailed sales analytics powered by Chart.js. Secure, role-based access control is implemented via custom hooks and Supabase Auth, ensuring that staff can perform their duties effectively while maintaining data integrity. API routes handle seamless data interactions, from fetching live orders and menu items to exporting comprehensive sales reports.

Feature Visual
Implementation

Real-time Data Sync via Supabase.

Supabase
Next.js API Routes
WebSockets
Role-Based Access

System Core // Efficient Large Data Export with Generator

async function* getOrdersGenerator(supabase) {
  let rangeStart = 0;
  const BATCH_SIZE = 100;

  while (true) {
    const { data: orders, error } = await supabase
      .from('orders')
      .select(`
        id, order_number, status, total_price, created_at, order_type,
        orderitems (id, quantity, price_at_order, variant_name,
          menuitems (name, category),
          orderitem_addons (addon_id, price_at_order, addons (name)))
      `)
      .order('created_at', { ascending: false })
      .range(rangeStart, rangeStart + BATCH_SIZE - 1);

    if (error) throw error;
    if (!orders || orders.length === 0) break;

    yield orders;
    
    if (orders.length < BATCH_SIZE) break;
    rangeStart += BATCH_SIZE;
  }
}
javascript
Next Project

Next Case Study

Ashly