Notifications
Catalog synced from Google Sheets — last updated 12 minutes ago.

All Discounted Products

By M.Srour

Add / edit one product

SKU is the main ID everything else (offers, imports) maps to — it's separate from the barcode. Editing an existing SKU here updates it everywhere.

Bulk upload master data

Upload a .csv or .xlsx. Columns: SKU, Name, NameAR, Brand, Category, Barcode, ProductLink, Description. Existing SKUs get updated, new ones get added — this is how you avoid re-typing brand/category/barcode for every offer.
Click to upload a .csv or .xlsx file
0 SKUs currently in the master list.

Product Master list

SKUName (EN)Name (AR)BrandCategoryBarcodeLink

1 Add manually

Pick a SKU from Product Master — name, brand, and category fill in automatically, so only the offer details need entering.
Flash shows automatically once an offer runs 7 days or less with over 40% off — the checkbox above is for flagging any other offer as Flash by hand too.

2 Upload Excel / CSV

Upload a .csv or .xlsx. Columns: SKU, Promo Type, Promo Value, Price, Old Price, Start Date, End Date, Channel, FlashManual (Y/N), MMFamily (free/percent/fixedprice/bundle — Mix & Match only), MMBuy, MMValue, DescriptionArOverride (optional custom Arabic phrase — leave blank to auto-generate). Name/brand/category aren't needed here — they're pulled from Product Master by SKU. The sample below has one example row per offer type and per attribute combination (both channels, online-only, flash on/off, missing old price, custom override, etc.) — check a real upload against it column-by-column before trusting a big batch.
Click to upload a .csv or .xlsx file
Export the current catalog to hand off or archive:

3 Sync from Google Sheets

Connect a shared sheet as the live source of truth (share it as "Anyone with the link → Viewer"). This auto-syncs every 5 minutes once a URL is entered here, plus you can always hit Sync now for an immediate pull. Note: this reads the sheet into the portal — a real instant "the moment I edit the sheet" push isn't possible from a page with no backend, so 5-minute polling is the closest safe equivalent.
Not connected yet.
These three input methods all write to the same product list — an offer added manually, imported from CSV, or synced from Sheets shows up identically to staff, including in every section below.
Editing template:

Wording & variables

All static text prints in Arabic (thermal is monochrome, so no color coding — wording and layout carry the distinction instead). Toggles control which variable fields print at all.
The default currency symbol is the official Saudi Riyal sign (Unicode U+20C1, standardized September 2025) — it's placed to the left of the price with a space, per SAMA's rule, regardless of the surrounding Arabic direction. This is a very new character: please do one real test print, since older printer firmware or fonts without an updated glyph set may not render it yet. If it doesn't print correctly on your Zebra, this field is fully editable — swap in whatever your printer supports.
Which phrase applies is decided per-offer by its Buy/Get numbers (set on the offer itself) — not chosen here. A custom Arabic override on any single offer always wins over either phrase.
Changes apply immediately — to every future preview and print, no save button needed.

Live preview

Rendered with a sample product so you can see the effect of each change right away.

Field positions & typography

Drag any field to reposition it, drag its right edge to resize it, or click it to edit bold/size. The dashed box and rulers show the actual 70mm × 52mm printable band — the ruler ticks are real millimeters, so you can see exactly where each field will land on the physical label.
Zoom:

Section order & descriptions

Reorder, rename, or hide any section — changes apply to Staff View immediately.

Customer sharing channels

Controls which options staff see on the "Send to customer" button. WhatsApp opens via whatever WhatsApp account is already logged into on that PC/browser (WhatsApp Web) — there's no separate login inside the portal. SMS opens the device's default messaging app, which generally only works on mobile, not desktop.

Push a notification

Sent to selected stores. Stays visible on staff screens until each staff member presses Acknowledge — this is logged below.

Notification log

Click a row to see exactly who acknowledged and when.
TitleSentTargetAcknowledged

Preview as a staff member

Testing tool for this demo only — lets you see the acknowledge flow from a specific store's point of view. Not shown to staff.

All offers — activate / deactivate

Turning an offer off hides it from staff immediately, without needing to change its dates. Table is capped to the first 300 matching rows for browser performance — use search to narrow it down.
SKUProductBrandTypeChannelEndsStatusFlashActive

Bupa master data — Google Sheet sync

This sheet only ever holds dispensed approvals — there's no separate list of "not yet dispensed" prescriptions. A number not on this list is what tells staff it's clear to dispense. Reads from this sheet auto-sync every 5 minutes once a URL is entered, plus Sync now for an immediate pull. Every time staff press Dispense, a new record (store, staff name, exact date & time) is added on this side — pushing that back into the actual sheet still needs the Apps Script bridge described below, since a static page can't write to Sheets on its own.
Last synced .
This demo keeps records in the browser and only simulates the write-back — a real deployment needs a small bridge (a Google Apps Script Web App endpoint is the simplest option) since a static page can't authenticate to Google Sheets directly. Happy to wire that up once it's confirmed available.

Dispensed records

Approval No.StoreDispensed ByDate & Time

Add new user

Demo auth only — passwords are stored as plain text in this prototype, same as the accounts shown on the login screen. A real deployment needs real hashed, server-side auth.

Bulk add users via CSV

Columns: Username, Password, Role (staff/admin), Store (store name — only needed for staff). Existing usernames get updated (password/role/store), new ones get added.
Click to upload a .csv or .xlsx file

All users

UsernameRoleStorePassword
Checking database connection…
By M.Srour