The Admin dashboard is the back-office control panel for La Previa Restobar. It gives administrators a real-time dashboard of sales metrics and table occupancy, a filterable product catalog with full create / edit / delete capabilities, a date-range sales report exportable to PDF or CSV, and a QR code that links to the public digital menu. Critically, the Admin is the only role that can add or modify products, set pricing, and configure inventory tracking.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/luisumit/LaPreviaRestobar/llms.txt
Use this file to discover all available pages before exploring further.
AdminMainScreen is reached from AppNavigation once userRole == UserRole.ADMIN is confirmed, and AdminStockScheduler.schedulePeriodicCheck(context) is triggered on every composition via LaunchedEffect(Unit).
Workflow
Monitor Operations
The Panel tab renders
AdminDashboardSection, which shows eight metric cards (sales today, sales this year, active orders, active products, best-selling product, occupied tables, low-stock count, out-of-stock count) and a StockAlertCard listing product names with alerts.Review Sales Reports
The Reportes tab renders
SalesReportSection. A SingleChoiceSegmentedButtonRow filters by AdminReportFilter (Día / Sem. / Mes / Año / Rango). A ReportRangeSelector card exposes two date pickers for custom ranges. Metrics include total sales, gross profit, total orders, charged orders, cancelled orders, products sold, and best-selling product. Reports are exported via viewModel.exportReportToPdf() or viewModel.exportReportToExcel() and saved to Downloads/LaPreviaReportes/.Manage Products
The Productos tab renders
ProductsAdminSection. A search field and SingleChoiceSegmentedButtonRow (All / Active / Out of Stock / Low Stock) filter the list. Each ProductAdminCard has edit and delete icon buttons. The floating + button calls viewModel.showProductForm(), opening ProductFormDialog. Tapping an edit icon calls viewModel.showProductForm(product), pre-populating the dialog for update mode.Screens
AdminMainScreen
AdminMainScreen is the single-screen entry point for the Admin role. It hosts a Scaffold whose top bar contains the app title, a test notification button (calls AdminStockScheduler.triggerImmediateCheck(context) for immediate verification), and a logout button. Below the top bar, AdminSectionTabs renders a four-tab TabRow (Panel / Reportes / Productos / QR) with a secondary indicator. The FAB only appears when selectedAdminTab == 2 (Productos).
ProductAdminCard
ProductAdminCard (in presentation/screens/admin/) renders a single product row inside ProductsAdminSection. It surfaces the product name, category, sale price, stock level, active status, and whether inventory tracking is enabled. Edit and delete icon buttons delegate to onEdit and onDelete lambdas passed from AdminMainScreen.
ProductFormDialog
ProductFormDialog is a Dialog-wrapped Surface with a scrollable Column of form fields. It is used for both create and edit modes — the product: Product? parameter determines which.
Form fields:
| Field | Type | Notes |
|---|---|---|
name | OutlinedTextField | Required; shows isError = true when blank |
description | OutlinedTextField | Optional; up to 3 lines |
salePrice | OutlinedTextField (numeric) | Maps to Product.salePrice: Double? |
costPrice | OutlinedTextField (numeric) | Used for gross profit calculation in reports |
trackInventory | Switch | When true, reveals the stock configuration section |
stock | OutlinedTextField (numeric) | Only shown when trackInventory == true; required when shown |
minStock | OutlinedTextField (numeric) | Threshold used by AdminStockWorker for low-stock alerts |
category | OutlinedTextField | Required; auto-populated from existing categories in uiState.categories |
imageUrl | OutlinedTextField | Optional URL for product image |
isActive | Switch | Inactive products are hidden from the waiter’s product catalog |
name.isNotBlank() && category.isNotBlank() && (!trackInventory || stock.toDoubleOrNull() != null).
AdminViewModel
AdminViewModel is a @HiltViewModel that exposes a single AdminUiState data class via a StateFlow, rather than individual StateFlows per field. This simplifies state management for a screen with many concurrent data concerns.
AdminUiState
Key Methods
| Method | Description |
|---|---|
createProduct(product) | Saves to Room with syncStatus = "PENDING", then pushes to Firebase if online |
updateProduct(product) | Updates Room with new version/timestamp, syncs to Firebase |
deleteProduct() | Deletes from Room and Firebase; uses uiState.selectedProduct |
showProductForm(product?) | Sets showProductForm = true and selectedProduct; null = create mode |
hideProductForm() | Resets form state |
manualSync() | Calls syncManager.syncProducts() and syncManager.downloadProducts() |
selectReportFilter(filter) | Rebuilds SalesReport for the chosen AdminReportFilter |
selectCustomReportRange(start, end) | Sets CUSTOM filter with normalised day boundaries |
exportReportToPdf() | Generates a PDF via PdfDocument and writes to MediaStore Downloads |
exportReportToExcel() | Generates a BOM-prefixed UTF-8 CSV and writes to MediaStore Downloads |
checkLowStockImmediately() | Queries Room for tracked products and updates uiState.warning |
refreshProducts() | Reloads from Room then Firebase |
Product CRUD Snippet
connectionStatusText Computed Property
ConnectionStatusBanner in the top bar and to the DashboardHeaderCard subtitle in ProductsAdminSection.
Low-Stock Notifications via WorkManager
Product stock alerts are delivered to the admin through Android’sWorkManager rather than through a foreground Firebase listener. This ensures alerts fire even when the app is in the background.
AdminStockWorker
AdminStockWorker is a @HiltWorker that extends CoroutineWorker. It is injected with AppDatabase by Hilt and runs on Dispatchers.IO.
sendNotification() posts a PRIORITY_HIGH notification on channel admin_stock_channel. The notification title summarises the counts (N agotados + M stock bajo) and the body lists up to three product names per category, with a “y N más…” suffix when the list is longer. Tapping the notification opens MainActivity with extras open_inventory = true and notification_type = "stock_alert".
AdminStockScheduler
AdminStockScheduler is a Kotlin object that wraps WorkManager enqueueing. It registers a PeriodicWorkRequest under the unique work name "admin_stock_worker" using ExistingPeriodicWorkPolicy.KEEP, so a second call during the same app session does not restart the timer.
cancelPeriodicCheck(context)— cancels the unique work by name.triggerImmediateCheck(context)— enqueues aOneTimeWorkRequestfor immediate execution; this is what the notification bell button inAdminMainScreen’s top bar calls during development and testing.
schedulePeriodicCheck is called inside LaunchedEffect(Unit) at the top of AdminMainScreen, so the periodic task is registered (or kept as-is if already scheduled) every time the admin enters their dashboard.