Skip to content

RuumiDev/wingzone-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WingZone — Comprehensive Project Reference

WingZone is a multimedia, multi-platform F&B group-ordering ecosystem built as a university project (Chapter 5 Multimedia Project). It consists of a native Android customer app, a React-based admin/kitchen web dashboard, and a Firebase serverless backend with ToyyibPay payment integration.


Table of Contents

  1. Project Objective & Problem Statement
  2. System Architecture
  3. Tech Stack & Frameworks
  4. Authentication & Security
  5. Firestore Database Schema
  6. Key Features & Workflows
  7. Firebase Cloud Functions
  8. Payment Gateway — ToyyibPay
  9. Admin Dashboard Pages
  10. Android App Screens
  11. Current Known Problems
  12. Future Enhancements
  13. Documentation Index

1. Project Objective & Problem Statement

Objective

Build a synchronous F&B group-ordering system that solves the chaotic, error-prone experience of placing food orders as a group at a dine-in restaurant. The system must:

  • Allow a group host to open a Lobby and share a join code / QR code / deep link with friends.
  • Let each member browse the menu independently and add items to their own sub-order in real time.
  • Aggregate all sub-orders into a single master kitchen ticket with a printed packaging sticker per seat.
  • Support both cash and online banking (FPX via ToyyibPay) payment flows.
  • Give kitchen and admin staff a real-time web dashboard to manage orders, inventory, and settings.

Problem Statement

Conventional dine-in ordering forces one person to collect everyone's choices verbally, increasing errors and wait times. Existing F&B apps (GrabFood, Foodpanda) target delivery only and do not support synchronised dine-in group ordering with per-seat identification or split-bill workflows. WingZone bridges this gap with a purpose-built Lobby system, thermal label output for each seat, and a real-time kitchen dashboard.


2. System Architecture

┌──────────────────────────────────────────────────────────────┐
│                      CLIENT LAYER                            │
│                                                              │
│   ┌─────────────────┐          ┌──────────────────────────┐ │
│   │  Android App    │          │  Admin / Kitchen Web     │ │
│   │  (Kotlin /      │          │  Dashboard (React +      │ │
│   │   Jetpack       │          │   TypeScript / Vite)     │ │
│   │   Compose)      │          │                          │ │
│   └────────┬────────┘          └────────────┬─────────────┘ │
└────────────┼───────────────────────────────┼───────────────┘
             │  Firebase SDK (real-time)      │  Firebase SDK
             ▼                               ▼
┌──────────────────────────────────────────────────────────────┐
│                  FIREBASE BACKEND LAYER                      │
│                                                              │
│  ┌─────────────┐  ┌──────────────┐  ┌────────────────────┐  │
│  │  Firestore  │  │  Firebase    │  │  Firebase Storage  │  │
│  │  (NoSQL DB) │  │  Auth        │  │  (Images/Sounds/   │  │
│  │             │  │  (Email/Pwd) │  │   Certs)           │  │
│  └─────────────┘  └──────────────┘  └────────────────────┘  │
│                                                              │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │  Cloud Functions (Node.js / TypeScript)                 │ │
│  │  - autoProgressIndividualOrders                         │ │
│  │  - onOrderConfirmed  (30s delay → preparing)            │ │
│  │  - autoDeliverReadyOrders  (5 min → delivered)          │ │
│  │  - autoProgressGroupOrders                              │ │
│  │  - onGroupOrderConfirmed                                │ │
│  │  - autoDeliverReadyGroupOrders                          │ │
│  │  - fixStuckOrders  (HTTP — admin utility)               │ │
│  │  - joinLobby        (HTTP — QR / link redirect)         │ │
│  │  - createToyyibPayBill  (payment initiation)            │ │
│  │  - paymentCallback      (ToyyibPay webhook)             │ │
│  └─────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
             │
             ▼
┌──────────────────────────────────────────────────────────────┐
│              PHYSICAL / HARDWARE LAYER                       │
│                                                              │
│   Thermal Label Printer (QZ Tray + jsrsasign)               │
│   Sticker Output: 40 mm × 30 mm — Seat ID + QR + Name       │
└──────────────────────────────────────────────────────────────┘

Deep-link scheme used throughout: wz://join?code=<LOBBY> and wz://payment/success?order_id=<ID>.


3. Tech Stack & Frameworks

3.1 Android Customer App

Concern Library / Tool
Language Kotlin
UI Jetpack Compose + Material 3
Architecture Single-Activity, MVVM, NavHost (Navigation Compose)
Concurrency Kotlin Coroutines + Flow
Image loading Coil (coil-compose, coil-svg)
QR generation ZXing (com.google.zxing:core 3.5.3)
QR scanning ML Kit Barcode Scanning + CameraX
Background tasks WorkManager
Firebase BOM 33.7.0 — Auth, Firestore, Storage, Messaging, Analytics
Animations Lottie (planned)
Min / Target SDK 27 / 36
Application ID wingzone.zenith

3.2 Admin & Kitchen Web Dashboard

Concern Library / Tool
Language TypeScript
Framework React 18
Build tool Vite 7.2.6
UI components Reactstrap (Bootstrap 5)
Styling SCSS Modules + Bootstrap Icons
Animations GSAP (@gsap/react)
Image cropping react-easy-crop, react-image-crop
Alerts SweetAlert2
Charts (Bootstrap Icon-based stat cards — full Recharts planned)
Firebase Firestore, Auth, Storage (JS SDK v9)
Thermal print QZ Tray + jsrsasign

3.3 Firebase Backend / Cloud Functions

Concern Library / Tool
Runtime Node.js (TypeScript)
Functions SDK firebase-functions v2
Admin SDK firebase-admin
File parsing busboy (multipart)
Payment ToyyibPay REST API (Malaysian FPX gateway)
Max instances 10 (global)

4. Authentication & Security

Authentication Flow

  1. Android app — Firebase Email/Password (FirebaseAuth). On first sign-up, a /users/{uid} document is created in Firestore with role: "user".
  2. Admin dashboard — Same Firebase Email/Password. After sign-in the AuthService reads the /users/{uid} document and rejects access unless role == "admin" or role == "kitchen".
  3. Session persistence — Dashboard stores the user object in localStorage; Android restores the FirebaseAuth current user on app restart.

Role Model

Role Access
user (customer) Own orders, own profile, lobby actions
kitchen Admin dashboard read + order status updates only
admin Full admin dashboard access + Firestore writes

Firestore Security Rules (highlights)

  • Custom Auth claim request.auth.token.admin == true is checked first (zero extra reads); falls back to users/{uid}.role == "admin".
  • Users can only read/write their own document. They cannot escalate their own role.
  • menuItems — public read, admin-only write.
  • orders / groupOrders — authenticated create, admin update (status), owner read.
  • appSettings — admin read/write only.
  • homeBanners — public read, admin write.
  • notifications — admin read/write.
  • reviews — authenticated create, admin moderation update.

Android Deep-Link Security

AndroidManifest.xml declares two intent-filter entries with autoVerify="true":

  • wz://join — lobby QR/link join
  • wz://payment — ToyyibPay payment callback

5. Firestore Database Schema

/menuItems/{id}
  name, description, category, price, imageUrl,
  isAvailable, requiresCustomization, displayOrder,
  flavors[], sizes[], addOns[],
  customizationOptions: {
    requiresFlavor, requiresBeverage, requiresDippingSauce,
    requiresBoneType, availableBoneTypes[],
    allowFriesExchange, friesExchanges[]
  },
  kitchenIngredients: { ingredients[] }

/orders/{id}                         ← individual orders
  userId, userName, items[], total,
  status: pending|confirmed|preparing|ready|delivered|cancelled,
  paymentMethod: cash|online,
  paymentStatus: unpaid|pending|paid,
  orderType, location, tableId,
  createdAt, confirmedAt, preparingAt, deliveredAt

/groupOrders/{id}                    ← lobby / group orders
  code, hostId, status,
  members[{ userId, name, items[], subtotal }],
  paymentSplit: { type, perMember },
  createdAt, confirmedAt, preparingAt, deliveredAt

/users/{uid}
  email, displayName, role,
  wzBalance, wzPoints, createdAt

/notifications/{id}
  type: order|system|info,
  title, message, orderId, orderType,
  orderTotal, customerName, groupOrderCode,
  createdAt, read

/appSettings/general
  taxRate (decimal), deliveryFee, minimumOrderAmount, updatedAt

/appSettings/adminPreferences
  darkMode, notificationSound, autoRefreshOrders,
  autoPrintReceipts, printerName, useThermalPrinter

/appSettings/notificationSound
  enabled, soundType, customSounds[], volume

/homeBanners/{id}
  title, subtitle, description, imageUrl,
  backgroundColor, accentColor, order, enabled

/reviews/{id}
  orderId, userId, userName, rating, comment,
  menuItemIds[], createdAt, isEnabled,
  moderationStatus: approved|pending|rejected

/availability/current
  flavors[], beverages[], sides[], dippingSauces[], boneTypes[]

6. Key Features & Workflows

6.1 Individual Order Flow

Customer browses menu
  → Selects item → Customisation dialog (flavor / bone type / fries exchange / dipping sauce)
  → Cart → Order Summary (subtotal + tax + delivery)
  → Checkout dialog: pick payment method
      ┌─ Cash → Order doc created immediately (paymentStatus: unpaid)
      │          Admin confirms payment manually
      └─ Online Banking → ToyyibPay bill created via Cloud Function
                        → WebView opened with payment URL
                        → On success: wz://payment/success?order_id=xxx
                        → Order doc created (paymentStatus: paid)
  → Cloud Functions auto-progress: confirmed → preparing (30s) → [admin marks ready] → delivered (5 min)
  → Order Tracking Screen shows real-time status

6.2 Group Order (Lobby) Flow

Host creates Lobby → gets 6-char code + QR code + shareable link
  → Friends scan QR / tap link (wz://join?code=xxx) / enter code manually
  → Each member sees shared lobby, browses menu independently
  → Host locks ordering → group order submitted
  → Cloud Functions auto-progress: confirmed → preparing (30s) → [admin marks ready] → delivered (5 min)
  → Admin kitchen dashboard shows aggregated kitchen ingredients list
  → Thermal sticker printed per seat (Seat ID + QR + member name)

6.3 Admin Order Management Workflow

  1. New order arrives → push/web notification fires (bell animation + toast + sound).
  2. Admin views individual or group orders tab on Orders page (grouped by date).
  3. Status changed via dropdown: Pending → Confirmed → Preparing → Ready → Delivered / Cancelled.
  4. Receipt modal or packaging sticker modal opened for printing.
  5. Kitchen ingredient aggregation shows raw materials needed per group order.

6.4 Menu Management

  • Admin adds/edits/deletes menu items with image upload (crop → Firebase Storage).
  • Categories: Combo Meals, Wings, Tenders, Burgers & Sandwiches, Local Favorites, Salads, Sides, Beverages.
  • Flavors (15 Wing Zone official sauces), bone types, fries exchange options, dipping sauces all configurable per item.
  • isAvailable toggled; mobile app listeners update in real time.

6.5 Availability Management

Admins toggle specific flavors, beverages, sides, dipping sauces, and bone types ON/OFF from the Availability page. State is persisted to /availability/current and reflected in the Android app's customisation dialog immediately via onSnapshot.

6.6 Tax & Settings Sync

Admin sets tax rate (%), delivery fee, and minimum order in Settings → App Configuration. Saved to appSettings/general. Android FirebaseCartRepository has a live snapshot listener — cart totals recalculate in real time on all connected devices.

6.7 Banner Management

Admin uploads and crops home-screen promotional banners via Banners page (stored in homeBanners collection + Firebase Storage). Banners have title, subtitle, colour scheme, display order, and enabled toggle.

6.8 Review Moderation

Users submit star ratings + comments after an order. Admin sees all reviews on the Reviews page with GSAP-animated cards. Actions: approve / reject / toggle visibility. moderationStatus field controls display in the app.

6.9 Notification System

  • Web dashboard uses onSnapshot on /orders — new orders trigger bell animation, toast pop-up, and configurable alert sound (9 built-in + custom upload via Firebase Storage).
  • Sound types: Default Beep, Bell, Chime, Alert, Urgent Alert, Kitchen Bell, Alarm, Siren, Custom.
  • Volume 0–100%; settings persisted to appSettings/notificationSound.
  • Android app uses Firebase Cloud Messaging (FCM) for push notifications.

6.10 Thermal Label Printing

  • Admin dashboard connects to a local QZ Tray instance over WebSocket.
  • Authentication via RSA/SHA-512 certificate (public/certs/digital-certificate.txt + private-key.pem).
  • Prints 40 mm × 30 mm sticker labels: Seat ID, member name, order items, QR code.
  • ThermalPrinterService is a singleton with connect(), printLabel(), disconnect().

7. Firebase Cloud Functions

Function Trigger Behaviour
autoProgressIndividualOrders orders/{id} created Skips cash/unpaid; immediately sets status: confirmed for paid orders
onOrderConfirmed orders/{id} updated Waits 30 s then moves to preparing if still confirmed
autoDeliverReadyOrders orders/{id} updated Waits 5 min then moves to delivered if still ready
autoProgressGroupOrders groupOrders/{id} created Immediately sets status: confirmed
onGroupOrderConfirmed groupOrders/{id} updated Waits 30 s then moves to preparing
autoDeliverReadyGroupOrders groupOrders/{id} updated Waits 5 min then moves to delivered
fixStuckOrders HTTP GET Utility — moves all pending paid orders to confirmed; skips cash orders
joinLobby HTTP GET ?code= Returns HTML page that fires wz://join?code= deep link with a fallback UI
createToyyibPayBill HTTP POST Creates a ToyyibPay bill and returns the payment URL
paymentCallback HTTP POST (webhook) Receives ToyyibPay confirmation, updates order paymentStatus: paid

8. Payment Gateway — ToyyibPay

ToyyibPay is a Malaysian FPX (online banking) aggregator.

Flow

CartScreen (online banking selected)
  → HTTP POST to createToyyibPayBill Cloud Function
  → Function calls ToyyibPay API → returns bill_code / payment URL
  → PendingOrderManager stores order in SharedPreferences (24 hr expiry)
  → App navigates to PaymentWebViewScreen
  → User completes FPX payment in WebView
  → ToyyibPay redirects to callback URL:
      https://us-central1-wingzone-app.cloudfunctions.net/paymentCallback
  → Webhook updates Firestore
  → Deep link wz://payment/success?order_id=xxx fires
  → MainActivity creates order document, clears cart, navigates to Order Tracking

Credentials (Development)

  • Secret Key: stored in Cloud Function source (⚠ move to Secret Manager for production)
  • Category Code: r90repsm
  • Functions URL: https://us-central1-wingzone-app.cloudfunctions.net

Payment Methods Supported

Method Flow
Cash Order created immediately; paymentStatus: unpaid; admin manually confirms
Online Banking (FPX) ToyyibPay WebView; order created only after successful callback

9. Admin Dashboard Pages

Page Route key Purpose
Login Firebase Email/Password; role check (admin/kitchen only)
Dashboard dashboard Real-time stats (today's orders, revenue, pending, active group orders); recent orders table
Menu menu CRUD for menu items; image crop/upload; flavor/bone/fries/sauce config
Orders orders Individual & group order tabs; status dropdown; receipt & sticker modals; kitchen ingredients view; date-grouped list
Availability availability Toggle flavors, beverages, sides, dipping sauces, bone types on/off
Users users Real-time list of all registered customers from Firestore
Banners banners Home-screen banner CRUD with image crop (react-easy-crop) and Firebase Storage upload
Reviews reviews Approve / reject / hide user reviews; GSAP-animated cards
Settings settings Dark mode, notification sound (with custom upload), printer config, tax/delivery/min-order sync
Notification Sound Settings notification-sounds Pick from 9 sounds, adjust volume, upload custom sound
Seed Menu seed One-time data seeder for initial menu population

10. Android App Screens

Screen File Description
Main / Launcher MainActivity.kt Single-activity host; NavHost; deep-link handler; payment flow listeners
Home / Menu MenuPage / menu composables Browse categories; item cards with images
Entree Customisation EntreeCustomizationDialog.kt Flavor chips, bone type, fries exchange, dipping sauce, size; Add to Cart
Cart CartScreen.kt Cart items, subtotal, tax, order summary, payment method picker, Checkout
Payment WebView PaymentWebViewScreen.kt Embedded WebView for ToyyibPay; URL-monitoring callback handler
Order Tracking OrderTrackingScreen.kt Real-time status updates for user's orders; status colour indicators
Group Order GroupOrderScreen.kt Lobby creation/joining (QR / code / link); member list; shared cart
Account AccountScreen.kt User profile (edit partially implemented)

11. Current Known Problems

# Area Problem Status
1 Cloud Functions createToyyibPayBill and paymentCallback code is ready but not yet deployed to Firebase Pending deploy
2 ToyyibPay credentials Secret key is hard-coded in function source — must be moved to Firebase Secret Manager before production Security debt
3 Thermal printer QZ Tray certificates (digital-certificate.txt, private-key.pem) missing from public/certs/; printer will not connect without them Needs certs
4 Alert sounds Built-in MP3 files (urgent-alert.mp3, kitchen-bell.mp3, alarm.mp3) not yet added to public/sounds/ Assets missing
5 User profile editing AccountScreen.kt exists but edit functionality (username, password, profile photo) is not implemented Partial — EditProfileDialog.kt TODO
6 Split-bill engine Group order payment splitting (per-member calculation, lock until all paid) is not implemented Placeholder only
7 Receipt / Invoice ReceiptModal and PackagingStickerModal exist in admin; Android PrintReceiptDialog.kt not created Partial
8 Group order full redesign GroupOrderScreen.kt exists but the complete UX redesign (bottom sheets, QR share, real-time member updates) from LOBBY-UX-REDESIGN.md is not finished In progress
9 FCM push notifications Firebase Cloud Messaging is declared in the Android manifest and firebase-messaging-ktx is a dependency, but server-side FCM send logic is not implemented in Cloud Functions Not wired
10 Availability sync race condition If admin marks a flavor unavailable while a customer is on the customisation screen, the UI does not re-validate the already-open dialog Minor UX gap

12. Future Enhancements

Category Enhancement
Ordering Delivery option with address input and live location tracking
Payment Split-bill engine — lock group order until every member's payment is confirmed
Payment E-wallet support (Touch 'n Go eWallet, Boost) via ToyyibPay or alternate gateway
Loyalty WZ Points / WZ Balance redemption at checkout (fields exist in user model)
Analytics Full revenue analytics dashboard with Recharts / Tremor — sales by category, hourly heatmap, top items
Notifications Server-side FCM push to Android — new order status updates, promotions
Profile Edit username, change password, upload profile photo (EditProfileDialog.kt)
Menu Stock count management — low-stock alerts to admin; auto-mark unavailable at zero
Banners Scheduled banner activation/expiry (start date / end date)
Reviews In-app review prompt after order delivered; response from admin
Group Order Lottie animations for lobby wait screen; member-ready indicators
Kitchen Display Dedicated KDS (Kitchen Display System) view on a tablet — auto-refresh, sound alerts, swipe-to-complete
Offline Support Firestore offline persistence for Android (already enabled for Auth); show cached menu when offline
Internationalisation Bahasa Malaysia / English toggle across both platforms
Accessibility Content descriptions on all Compose composables; contrast ratio audit on admin dashboard
CI/CD GitHub Actions — Android APK build + Firebase App Distribution; Functions deploy on merge to main

13. Documentation Index

File Contents
ADMIN-ENHANCEMENTS-GUIDE.md Custom notification sounds, direct image upload setup
ADMIN-SETTINGS-GUIDE.md Tax, delivery fee, minimum order configuration
COMPLETE-IMPLEMENTATION-STATUS.md Checklist of all 16 implementation issues and their state
FIXES-2025-01-23.md Notification overflow, fries exchange, dine-in UX, scroll fixes
LOBBY-UX-REDESIGN.md Full UX spec for Group Order / Lobby redesign (ZUS-style)
NOTIFICATION-SYSTEM.md Admin dashboard real-time notification animations and Firebase structure
PAYMENT-GATEWAY-INTEGRATION.md Code changes required for CartScreen → PaymentWebView split
PRODUCTION-READY-PLAN.md Phased plan of critical, dashboard, and UX fixes
RECENT-FIXES-DEC-2025.md December 2025 fixes — checkout button, add-to-cart visibility, bone type, admin config
TAX-CONFIGURATION-GUIDE.md How tax rate flows from admin settings to mobile cart
TOYYIBPAY-INTEGRATION.md ToyyibPay setup, credentials, Android config, deploy steps
TOYYIBPAY-STATUS.md Current integration completion checklist
CartScreen-Checkout-Logic-Update.kt Kotlin snippet for cash vs online banking checkout split

Last updated: May 26, 2026

/notifications

  • Real-time notifications
  • Fields: type, title, message, createdAt, read

/orders

  • Customer orders

/settings

  • App configuration /availability
    • Item availability toggles

---

## 📖 How to Use This Documentation

1. **For Developers**: Start with technical implementation docs
2. **For Admins**: Check the Admin Dashboard Guide
3. **For Users**: Refer to the Android App Guide
4. **For Issues**: Check Issues Resolved document

---

## 🆘 Support

If you encounter any issues:
1. Check the relevant documentation file
2. Review the Issues Resolved document
3. Check Firebase console for data issues
4. Review browser/Android console for errors

---

## 📝 Contributing to Documentation

When adding new features:
1. Document in appropriate .md file
2. Update this README index
3. Save all .md files in /docs folder
4. Keep README.md in root for project overview

---

Last Updated: December 5, 2025

About

WingZone Restaurant Management System featuring a React/TypeScript admin dashboard, a Kotlin Android application, and real-time Firebase integration.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors