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.
Sync from Google Sheets
Same columns as the CSV upload. Auto-syncs every 5 minutes once a URL is entered here (share the sheet as "Anyone with the link → Viewer" first).
Last synced never.
Product Master list
SKU
Name (EN)
Name (AR)
Brand
Category
Barcode
Link
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.
4 Inventory — stock per store
Powers "Only items in stock at my store" on the staff Print All screen. Sheet columns: SKU, Store Number, Quantity — Store Number must match the "Store Number" field on each store in Manage Stores.
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.
Delete sample data
Wipes all test offers, the product catalog, notifications, and Bupa test records (Bupa only if you check the box below) — before you start loading real data. Never touches your real stores or user accounts. Cannot be undone.
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.
Field positions & typography
Drag any field to reposition it, drag its right edge to resize it, or click it to edit bold/size. Shown here is the FULL physical label (70mm × 139mm) — the hatched zones above and below are outside the printer's printable window and will never actually print, no matter what's placed there; only the clear band in the middle (8–13.5cm) can hold fields. The ruler ticks are real millimeters.
Zoom:
Photo opacity
If you're printing onto blank pre-printed thermal roll stock, upload a real photo of it here — it'll show faded behind the fields below so you can drag each one to line up exactly with the real label, instead of guessing coordinates. This photo is never printed, it's only a visual guide while editing.
Live preview
Rendered with a sample product so you can see the effect of each change right away — including drags and resizes below, so you can edit and check the result side by side without scrolling.
Preview family:
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.
Title
Sent
Target
Acknowledged
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. Ended offers stay listed here for you to manage even though staff no longer see them anywhere except "Ended This Week."
0 selected
SKU
Product
Brand
Type
Channel
Ends
Status
Flash
Focus
Active
Edit
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.
Store
Dispensed By
Date & Time
Add new user
Passwords are hashed (bcrypt) and checked server-side on login — real, not a demo shortcut. Type carefully: this password box is plain text on screen so you can see what you're entering, but nothing is ever stored or transmitted unhashed.
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
Sync from Google Sheets
Same columns as the CSV upload. Auto-syncs every 5 minutes once a URL is entered here (share the sheet as "Anyone with the link → Viewer" first).
Last synced never.
All users
Username
Role
Store
Password
Checking database connection…
Offers by type
Offers by channel
Top categories
Top brands
Mix & Match by family
Offers by data source
Offers created — last 12 months
Top creators
Print report
Labels printed per store, from the day this was turned on. Older prints were never logged and can't be recovered.
Pick a range and click Run.
Store
Labels printed
Unique items
Active days
Single
Selected
Print all
Print list
Add a barcode manually
Link one extra barcode to a SKU — for the case where a scan comes back "not found" and you already know which item it is.
Bulk upload barcodes
Upload a .csv or .xlsx with columns: Barcode, SKU — one row per barcode. An item with several barcodes gets several rows with the same SKU. Existing barcodes get their SKU updated; new ones are added.
Click to upload a .csv or .xlsx file
All barcodes (0)
Barcode
SKU
Source
Updated by
Updated
Add one store
An internal ID gets generated automatically from the name — you never need to think about it. Re-adding a store with the exact same name updates it instead of creating a duplicate.
Bulk add via CSV
Columns: Name, Store Number (optional). Built for adding many stores at once — 150+ works fine.
Click to upload a .csv or .xlsx file
Sync from Google Sheets
Same columns as the CSV upload. Auto-syncs every 5 minutes once a URL is entered here.
Last synced never.
All stores
Store name
Store number
Internal ID
Add / edit a coupon
Re-adding the same code updates it instead of creating a duplicate.
Upload eligible items for a coupon
Only SKUs on this list are considered eligible when staff check a coupon — re-uploading replaces the previous list for that coupon entirely.
Click to upload a .csv or .xlsx file (SKU, Name)
All coupons
Code
Discount
Min order
Max discount
Valid
Eligible items
Active
Add / edit a contest
Staff earn direct commission on items in this list during the contest window — not a discount, a focus/incentive tool.
Upload items for a contest
Re-uploading replaces the previous item list for that contest entirely.
Click to upload a .csv or .xlsx file (SKU, Name, Commission)
All contests
Name
Description
Valid
Items
Active
Add / edit a flyer
Staff see a button for each flyer below, but ONLY once it has a link — you can create a named slot ahead of time and paste the link in whenever it's ready.
All flyers
Name
Link
Order
Active
By M.Srour
Reset password
Send to customer
Include the country code, no + or spaces needed. Leave blank to pick a contact from WhatsApp instead.
No product link is set for this SKU yet — add one in Admin → Product Master, then it'll be ready to send here.
Flyers & catalogs
Open a flyer, or send it straight to a customer's phone on WhatsApp.
Bupa dispense check
Check an approval number before dispensing — confirms it hasn't already been dispensed at another store.
Scan barcode
Point a camera at the barcode
Tip: a USB or Bluetooth handheld scanner works automatically — just click the search box and scan, no need to open this window.
Print list
Add an item
Add everything from a brand or category
In the list
Scan to print list
In list: 0
Starting camera…
This session
Label preview
Edit offer
SKU — SKU itself can't be changed here; delete and re-add if it's genuinely wrong.
Did the labels print OK?
If you're not sure, choose No or close this — nothing will be marked as printed, and you can safely try again.