Files
meezi/web/admin/messages/en.json
T
soroush.asadi 024a455ab3 fix: menu item/category create, demo banner reach, token refresh, blog publish
Dashboard & API bug fixes for owner-reported breakage:

- MenuController validators (PosValidators): NameEn was required but the
  dashboard sends null when blank, so every manual menu-item create failed
  and category create failed 100% (the form never sends nameEn). Now optional.
- DemoDataBanner: only showed when a cafe was exactly empty, so
  showcase-seeded cafes (2-3 cats / 3-5 items) could never trigger the
  one-click seed. Widened gate to sparse menus (<5 cats && <10 items) and
  added a clear "nothing to add" message when already populated.
- client.ts: added one-time JWT refresh-and-retry on 401 (shared in-flight
  promise) before bouncing to /login. Expired access tokens silently broke
  ticket list, add-table, and other reads.
- Surface API errors as toasts on menu + table mutations (were swallowed
  silently, so failures looked like "nothing happens").
- Admin blog editor: saving an edit dropped IsPublished (defaulted false,
  silently unpublishing the post on every save); now persisted with a
  toggle. Also hoisted the inner Field component to module scope - it was
  remounting every input on each keystroke and dropping focus.
- Admin integrations: replaced raw radio gateway selector with a styled
  RadioDot matching the iOS toggles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:25:34 +03:30

1434 lines
46 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"common": {
"save": "Save",
"cancel": "Cancel",
"confirm": "Confirm",
"delete": "Delete",
"search": "Search",
"loading": "Loading...",
"logout": "Log out",
"language": "Language",
"comingSoon": "Coming soon",
"edit": "Edit"
},
"confirm": {
"title": "Confirm action",
"confirm": "Confirm",
"cancel": "Cancel"
},
"notify": {
"saved": "Saved",
"errorGeneric": "Something went wrong. Please try again."
},
"brand": {
"name": "Meezi"
},
"languages": {
"fa": "فارسی",
"ar": "العربية",
"en": "English"
},
"auth": {
"title": "Sign in to Meezi",
"subtitle": "We will send a verification code to your phone",
"phone": "Mobile number",
"phonePlaceholder": "09121234567",
"sendOtp": "Send code",
"otp": "Verification code",
"otpPlaceholder": "6 digits",
"verify": "Sign in",
"resend": "Resend",
"rateLimited": "Too many code requests. Wait up to one hour or contact support.",
"notFound": "No account found for this mobile number.",
"smsFailed": "Could not send SMS. Please try again.",
"invalidOtp": "Invalid or expired verification code."
},
"nav": {
"pos": "POS",
"tables": "Tables",
"crm": "CRM",
"coupons": "Coupons",
"menu": "Menu",
"inventory": "Inventory",
"hr": "HR",
"reports": "Reports",
"expenses": "Expenses",
"reviews": "Reviews",
"reservations": "Reservations",
"sms": "SMS",
"taxes": "Taxes",
"branches": "Branches",
"subscription": "Plan & billing",
"support": "Support",
"settings": "Settings",
"kds": "Kitchen",
"queue": "Daily queue"
},
"dashboard": {
"cafeName": "Demo Cafe",
"planPro": "Pro",
"online": "Online",
"offline": "Offline",
"activePlan": "Active plan"
},
"pos": {
"order": "Order",
"table": "Table",
"total": "Total",
"subtotal": "Subtotal",
"tax": "Tax",
"discount": "Discount",
"confirmOrder": "Confirm & pay",
"modeOrder": "Take order",
"modePay": "Pay",
"takeOrder": "Order taking",
"submitOrder": "Submit order",
"submitOrderAndPay": "Submit order & pay",
"orderPaidNew": "Order submitted and paid",
"orderPaidAdd": "Items added and paid",
"posDeviceSent": "Amount sent to POS terminal",
"posDeviceError": "Could not send amount to POS terminal",
"posDeviceNotConfigured": "POS terminal not configured — payment recorded in Meezi only",
"posDeviceConnectionFailed": "Could not connect to POS terminal",
"posDeviceTimeout": "POS terminal timed out",
"posDeviceRejected": "POS terminal rejected the payment",
"posDeviceNoBranch": "No branch selected for POS payment",
"kitchenSlip": "Kitchen ticket (preview & print)",
"queueNumber": "Queue #{number}",
"orderPlaced": "Order saved — go to Pay to collect payment",
"guestName": "Guest name",
"guestNamePlaceholder": "e.g. Ali",
"needTableOrName": "Select a table, customer, or guest name",
"openOrders": "Open orders",
"openOrdersHint": "Orders not paid yet",
"noOpenOrders": "No orders waiting for payment",
"payOrder": "Payment",
"payFor": "Pay for",
"selectOrderToPay": "Select an order from the list",
"confirmPay": "Collect payment",
"confirmPayCash": "Collect payment (cash)",
"confirmPayCard": "Collect payment (card)",
"confirmPayCredit": "Collect payment (credit)",
"confirmPaySplit": "Collect payment (split)",
"previewBill": "Preview & print bill",
"paySuccess": "Payment recorded",
"payError": "Payment failed",
"payNeedsOpenShift": "Open the register shift for this branch before taking payment",
"cancelOrder": "Cancel order (no payment)",
"cancelOrderConfirm": "Customer left without paying? The order will be cancelled and the table freed.",
"cancelOrderSuccess": "Order cancelled",
"cancelOrderError": "Could not cancel order",
"itemsCount": "items",
"applyCoupon": "Apply coupon",
"couponPlaceholder": "Coupon code",
"couponCode": "Coupon code",
"selectTable": "Table",
"emptyCart": "Cart is empty",
"cash": "Cash",
"card": "Card",
"clearCart": "Clear",
"allCategories": "All",
"searchItems": "Search items",
"searchItemsPlaceholder": "Search by item name…",
"searchNoResults": "No items match your search",
"reservationBanner": "Reservation: {name} — add items and tap Confirm & pay",
"orderSuccess": "Order placed",
"orderError": "Failed to place order",
"orderInvalid": "Invalid order (check menu items or table)",
"orderNotOpen": "This order is no longer open",
"orderValidation": "Invalid order details",
"nothingPending": "No new items to send to the kitchen",
"couponApplied": "Coupon «{code}» applied — {amount} off",
"couponActive": "Coupon {code}",
"couponRemoved": "Coupon removed",
"removeCoupon": "Remove",
"couponInvalid": "Invalid coupon code",
"couponExpired": "This coupon has expired",
"couponNotStarted": "This coupon is not active yet",
"couponLimitReached": "This coupon has reached its usage limit",
"couponMinOrder": "Minimum order amount not met",
"couponCartEmpty": "Add items to the cart first",
"couponRequired": "Enter a coupon code",
"guestPhone": "Guest phone",
"guestPhonePlaceholder": "09121234567",
"selectTableBoard": "Select table",
"loadingTables": "Loading tables...",
"selectBranchForTables": "Select a branch first",
"noTablesOnBoard": "No tables for this branch. Add tables in the Tables screen.",
"tablesLoadError": "Could not load tables",
"retryTables": "Try again",
"manageTablesLink": "Go to Tables",
"sessionActive": "Active table session",
"addToOrder": "Added to table order",
"void": "Void",
"voidItem": "Void item",
"voided": "Voided",
"confirmVoid": "Are you sure you want to void this item?",
"voidError": "Could not void item",
"transferTable": "Transfer table",
"selectTargetTable": "Select destination table",
"transferSuccess": "Order transferred successfully",
"transferError": "Could not transfer table",
"tableNotAvailable": "Table is being cleaned",
"tableOccupied": "Table is already occupied",
"searchOpenOrder": "Table, name, phone, or order ID...",
"paidSoFar": "Paid",
"remaining": "Remaining",
"splitPayments": "Split payment",
"addPaymentRow": "Add payment row",
"credit": "Credit",
"paySelectTable": "Pick table (occupied)",
"payPickByName": "Or pick by name / open order list",
"payOpenOrdersHint": "Tap an occupied table, use the table dropdown, or search by name/phone",
"allTables": "All tables",
"noOrderOnTable": "No open order on this table",
"noOpenOrdersOnTable": "No open orders for this table",
"customerSection": "Customer",
"existingCustomer": "Existing",
"newCustomer": "New guest",
"customerSearchPlaceholder": "Name, phone, or national ID...",
"customerSearchHint": "Type at least 2 characters to search",
"customerNotFound": "No customer found — add as new guest",
"customerSaved": "Customer saved to CRM",
"customerSaveError": "Could not save customer",
"customerPhoneExists": "Phone already registered — search and select",
"newCustomerHint": "Use for this order only, or tap Add customer to save to CRM"
},
"print": {
"printReceipt": "Print receipt",
"printKitchen": "Send to kitchen",
"success": "Receipt printed successfully",
"notConfigured": "Printer IP is not configured",
"connectionFailed": "Could not connect to printer",
"testPrint": "Test print",
"printerSettings": "Printer settings",
"receiptPrinter": "Receipt printer",
"kitchenPrinter": "Kitchen printer",
"paperWidth": "Paper width",
"autoCut": "Auto cut",
"port": "Port",
"receiptHeader": "Receipt header",
"receiptFooter": "Receipt footer",
"wifiOnReceipt": "WiFi password on receipt",
"saveSettings": "Save settings",
"settingsSaved": "Printer settings saved",
"noBranchForPrinter": "Add a branch before configuring printers.",
"testPageHint": "Sends a test ticket to your saved printers. Configure IP and port under Printer settings first.",
"testPrintReceipt": "Test receipt printer",
"testPrintKitchen": "Test kitchen printer",
"configurePrinters": "Open printer settings",
"posDeviceSection": "Card POS terminal",
"posDeviceHint": "On card payment, the amount is sent via HTTP (POST /pay) to the device on your LAN.",
"posDeviceIp": "POS device IP address"
},
"receipt": {
"table": "Table",
"order": "Order",
"guest": "Guest",
"total": "Total",
"print": "Print",
"close": "Close",
"thankYou": "Thank you for your visit",
"kitchenTitle": "Kitchen / bar ticket",
"billTitle": "Customer bill",
"kitchenFooter": "— For kitchen —",
"payment": {
"cash": "Cash",
"card": "Card",
"credit": "Credit"
}
},
"crm": {
"title": "Customers",
"searchPlaceholder": "Name, phone, or national ID...",
"addCustomer": "Add customer",
"name": "Name",
"phone": "Phone",
"nationalId": "National ID",
"birthDate": "Birth date (Jalali)",
"group": "Group",
"loyaltyPoints": "Points",
"noCustomers": "No customers found",
"groups": {
"Regular": "Regular",
"Vip": "VIP",
"New": "New",
"Employee": "Employee"
},
"wizard": {
"titleCreate": "Add customer",
"titleEdit": "Edit customer",
"stepOf": "Step {current} of {total}",
"steps": {
"contact": "Contact",
"profile": "Profile",
"loyalty": "Group & points",
"confirm": "Review"
},
"back": "Back",
"next": "Next",
"birthHint": "Jalali format, e.g. 1400/01/01",
"referredBy": "Referred by (optional)",
"loyaltyCreateHint": "Loyalty points can be adjusted after the customer is created.",
"errors": {
"duplicatePhone": "This phone number is already registered.",
"generic": "Could not save. Please try again."
}
}
},
"coupons": {
"title": "Coupons",
"addCoupon": "New coupon",
"code": "Code",
"type": "Type",
"value": "Value",
"usage": "Usage",
"active": "Active",
"inactive": "Inactive",
"types": {
"Percentage": "Percentage",
"FixedAmount": "Fixed amount",
"FreeItem": "Free item"
},
"noCoupons": "No coupons yet"
},
"hr": {
"title": "Human resources",
"tabs": {
"attendance": "Attendance",
"leave": "Leave",
"payroll": "Payroll"
},
"myAttendance": "My attendance",
"clockIn": "Clock in",
"clockOut": "Clock out",
"approve": "Approve",
"noLeave": "No pending leave requests",
"paid": "Paid",
"markPaid": "Mark paid",
"employeeCount": "Employees",
"monthYear": "Payroll month"
},
"reviews": {
"title": "Customer reviews",
"summary": "Average rating",
"reviewCount": "{count} reviews",
"empty": "No reviews yet.",
"ownerReply": "Cafe reply",
"reply": "Reply",
"replyPlaceholder": "Write your reply..."
},
"sms": {
"title": "SMS marketing",
"message": "Message",
"messagePlaceholder": "Write your SMS text...",
"targetGroup": "Target group",
"allCustomers": "All customers",
"send": "Send",
"usage": "Usage this month",
"unlimited": "Unlimited",
"sent": "Sent",
"failed": "Failed"
},
"reports": {
"title": "Reports & analytics",
"subtitle": "Sales summary from daily snapshots",
"exportCsv": "Download CSV",
"fromDate": "From",
"toDate": "To",
"branch": "Branch",
"allBranches": "All branches",
"preset": {
"7d": "7 days",
"30d": "30 days",
"90d": "90 days"
},
"kpiTotalRevenue": "Total revenue",
"kpiTotalOrders": "Orders",
"kpiAvgOrder": "Avg. order value",
"kpiNetIncome": "Net income",
"kpiTotalExpenses": "Total expenses",
"vsPrevious": "vs previous period",
"revenueChartTitle": "Daily revenue trend",
"paymentMixTitle": "Payment methods",
"branchCompareTitle": "Branch comparison",
"topProductsTitle": "Top products",
"colProduct": "Product",
"colQuantity": "Qty",
"colRevenue": "Revenue",
"revenue": "Revenue",
"cash": "Cash",
"card": "Card",
"credit": "Credit",
"noData": "No data",
"loading": "Loading...",
"csvDate": "Date",
"csvBranch": "Branch",
"csvTotalRevenue": "Total revenue",
"csvTotalOrders": "Orders",
"csvAvgOrder": "Avg order",
"csvCash": "Cash",
"csvCard": "Card",
"csvCredit": "Credit",
"csvNetIncome": "Net income",
"csvVoids": "Voids",
"csvVoidAmount": "Void amount",
"csvExpenses": "Expenses"
},
"expenses": {
"title": "Expenses",
"subtitle": "Log and track branch expenses",
"addExpense": "Log expense",
"listTitle": "Expense log",
"branch": "Branch",
"fromDate": "From",
"toDate": "To",
"periodTotal": "Period total",
"category": "Category",
"amount": "Amount",
"note": "Note",
"notePlaceholder": "Optional",
"linkOpenShift": "Deduct from open register (cash withdrawal)",
"noOpenShift": "No open shift — expense will not link to a register",
"colDate": "Date",
"colCategory": "Category",
"colNote": "Note",
"colAmount": "Amount",
"loading": "Loading...",
"empty": "No expenses logged",
"rowCount": "{count} rows",
"categories": {
"Supplies": "Supplies",
"Utilities": "Utilities",
"Salary": "Salary",
"Rent": "Rent",
"Maintenance": "Maintenance",
"Other": "Other"
}
},
"queue": {
"title": "Daily queue",
"subtitle": "Ticket numbers restart at 1 each day (Iran calendar)",
"nowServing": "Now serving",
"lastIssued": "Last issued",
"waitingCount": "{count} waiting",
"issueNext": "New number",
"callNext": "Call next",
"customerLabelPlaceholder": "Guest name (optional)",
"dailyResetHint": "Numbers reset at midnight Iran time.",
"empty": "No tickets issued today yet.",
"issuedOnOrder": "Queue #{number}",
"status": {
"Waiting": "Waiting",
"Called": "Called",
"Done": "Done",
"Cancelled": "Cancelled"
}
},
"kds": {
"title": "Kitchen display",
"pending": "Pending",
"preparing": "Preparing",
"ready": "Ready",
"table": "Table",
"noOrders": "No orders"
},
"tables": {
"title": "Table management",
"addTable": "Add table",
"number": "Table number",
"capacity": "Capacity",
"floor": "Floor",
"floorPlan": "Floor plan",
"empty": "No tables yet.",
"emptyBranch": "No tables for this branch.",
"allBranches": "All branches",
"branchFilter": "Branch filter",
"branch": "Branch",
"branchUnassigned": "No branch",
"branchHint": "Tables belong to your café; branch is optional for POS and reports.",
"tableLabel": "Table {number}",
"meta": "Cap. {capacity} · Floor {floor}",
"status": {
"Free": "Free",
"Busy": "Occupied",
"Reserved": "Reserved",
"Cleaning": "Cleaning",
"free": "Available",
"occupied": "Occupied",
"reserved": "Reserved",
"cleaning": "Cleaning"
},
"markCleaning": "Needs cleaning",
"markReady": "Ready for guests",
"activeOrder": "Active order",
"reserved": "Reserved",
"printQr": "Print QR",
"qrMenuUrl": "Guest menu link",
"openQrUrl": "Open",
"copyQrUrl": "Copy link",
"qrUrlCopied": "Link copied",
"qrUrlCopyFailed": "Could not copy link",
"reprintHint": "Lost QR? Same button — code never changes.",
"deactivate": "Deactivate",
"inactive": "Inactive",
"edit": "Edit",
"editTable": "Edit table",
"reactivate": "Reactivate",
"saveTable": "Save table",
"media": "Table image & video",
"section": "Section",
"sections": "Sections",
"addSection": "Add section",
"noSection": "No section",
"noSectionsYet": "No sections defined yet.",
"sectionTableCount": "{count} tables",
"sectionHasTables": "This section has tables and cannot be deleted",
"tableHasOpenOrder": "This table has an open order",
"deleteTable": "Delete table",
"deleteTableConfirm": "Permanently delete this table? (Only when it has no open order)",
"deleteError": "Could not delete table",
"createError": "Could not add table",
"cleaningError": "Could not update cleaning status"
},
"menuAdmin": {
"title": "Menu management",
"subtitle": "Images, prices, and per-item discounts",
"categories": "Categories",
"items": "Items",
"addCategory": "New category",
"addItem": "Add item",
"name": "Name",
"nameEn": "English name (for international guests)",
"price": "Price (T)",
"category": "Category",
"available": "Available",
"unavailable": "Unavailable",
"discountPercent": "Discount (%)",
"discountBadge": "off",
"uploadImage": "Upload image",
"imageReady": "Image ready",
"empty": "No menu items yet.",
"editItem": "Edit",
"editCategory": "Edit category",
"categoryIcon": "Icon (emoji)",
"categoryImage": "Category image",
"iconTabPreset": "Preset icons",
"iconTabEmoji": "Emoji",
"iconTabImage": "Upload image",
"iconStyleLabel": "Design style",
"iconPreview": "Preview:",
"clearIconPreset": "Clear icon",
"clearIconEmoji": "Clear emoji",
"categoryIconCustom": "Or custom emoji",
"iconPresetGroupDrinks": "Drinks",
"iconPresetGroupFood": "Food",
"iconStyles": {
"flat": "Flat",
"modern": "Modern",
"real": "Real",
"minimal": "Minimal",
"outline": "Outline",
"soft": "Soft",
"bold": "Bold",
"gradient": "Gradient",
"pastel": "Pastel",
"duotone": "Duotone"
},
"iconEmojiGroups": {
"hotDrinks": "Hot drinks",
"coldDrinks": "Cold drinks",
"breakfast": "Breakfast",
"mains": "Main dishes",
"pastaPizza": "Pasta & pizza",
"desserts": "Desserts",
"salads": "Salads",
"seafoodGrill": "Grill & seafood",
"snacks": "Snacks & fast food",
"vegan": "Plant-based",
"specials": "Specials",
"general": "General"
},
"iconPresets": {
"drinks-hot": "Hot coffee",
"drinks-cold": "Cold drinks",
"drinks-tea": "Tea",
"drinks-juice": "Juice",
"drinks-milkshake": "Milk & smoothies",
"drinks-alcohol": "Wine",
"drinks-beer": "Beer",
"breakfast": "Breakfast",
"food-mains": "Main dishes",
"food-fastfood": "Fast food",
"food-rice": "Rice dishes",
"pasta-pizza": "Pasta & pizza",
"dessert": "Dessert",
"ice-cream": "Ice cream",
"bakery": "Bakery",
"salad": "Salad",
"grill": "Grill",
"seafood": "Seafood",
"snacks": "Sandwich",
"snacks-sweet": "Pastries",
"appetizers": "Appetizers",
"vegan": "Plant-based",
"fruits": "Fruits",
"specials": "Specials",
"chef-special": "Chef's pick",
"generic": "General"
},
"media": "Image & video",
"tabCatalog": "Catalog",
"tabBranch": "Branch settings",
"selectBranchForOverrides": "Select a branch above to manage its menu overrides."
},
"branchMenu": {
"title": "Branch Menu",
"name": "Name",
"masterPrice": "Master Price",
"branchPrice": "Branch Price",
"availability": "Status",
"available": "Active",
"unavailable": "Hidden",
"resetOverride": "Reset",
"savePrice": "Save",
"actions": "Actions",
"priceOverridePro": "Price overrides require Pro plan",
"overrideActive": "Branch override active",
"confirmReset": "Reset this item to catalog defaults?",
"loading": "Loading..."
},
"media": {
"uploadImage": "Upload image",
"uploadVideo": "Upload video",
"removeImage": "Remove image",
"removeVideo": "Remove video",
"upload3dTitle": "3D view (optional)",
"upload3dHint": "GLB file up to {maxMb} MB — guests can rotate the item on touch",
"upload3dPhotoCount": "Besides cover photo: one GLB is enough. For photo-based 360° (future): {min}{ideal} photos from different angles",
"upload3d": "Upload 3D model",
"remove3d": "Remove model",
"upload3dReady": "3D model will show on the QR menu"
},
"taxes": {
"title": "Taxes",
"subtitle": "Rates applied to menu categories",
"addTax": "Add tax",
"name": "Name (e.g. VAT)",
"rate": "Rate (%)",
"hint": "Default tax applies to new categories. Taraz submission is in Settings.",
"empty": "No taxes defined.",
"default": "Default",
"setDefault": "Set default",
"delete": "Remove",
"deleteConfirm": "Remove \"{name}\" from the list? Menu categories using this tax will switch to the next default tax (or no tax).",
"required": "Required",
"optional": "Optional",
"ownerOnly": "Only the café owner can change taxes."
},
"branches": {
"label": "Branch"
},
"inventory": {
"title": "Inventory",
"subtitle": "Materials, menu recipes, and auto-deduction on orders",
"description": "Track ingredient quantities and reorder levels.",
"tabMaterials": "Materials",
"tabRecipes": "Menu recipes",
"addIngredient": "New ingredient",
"name": "Name",
"unit": "Unit",
"unitHint": "g, ml, pcs...",
"quantity": "On hand",
"parLevel": "Full stock (e.g. 500 g)",
"unitCost": "Unit cost (Toman)",
"warningPercent": "Warning %",
"reorderLevel": "Reorder level",
"reorder": "Reorder at",
"warningAt": "Warn below",
"stockValue": "Stock value",
"lowStock": "Low",
"lowStockAlert": "Below warning level — refill these materials",
"adjust": "Apply",
"adjustDelta": "+/- qty",
"adjustNote": "Manual adjustment",
"adjusted": "Stock updated",
"created": "Ingredient added",
"empty": "No ingredients yet.",
"defaultUnit": "pcs",
"selectMenuItem": "Menu item",
"selectMenuItemPlaceholder": "Select...",
"recipeLines": "Per sold unit",
"perUnit": "Qty",
"pickIngredient": "Ingredient",
"addLine": "Add",
"saveRecipe": "Save recipe",
"recipeSaved": "Recipe saved",
"materialCostPerUnit": "Material cost / unit",
"recipeHint": "Example: 10 g coffee per espresso — 10 orders use 100 g."
},
"qr": {
"brand": "Meezi",
"notFound": "Table not found",
"loadError": "Failed to load",
"tableLabel": "Table {number}",
"hint": "Open the Meezi app to order, or ask at the counter.",
"discoverCta": "Discover cafés on Meezi"
},
"qrMenu": {
"loading": "Loading...",
"welcome": "Welcome",
"tableLabel": "Table",
"tableNotFound": "Table not found or menu unavailable",
"tableCleaning": "This table is being cleaned — please ask staff",
"loadError": "Could not load menu",
"scanAgain": "Please scan the QR code again",
"addToCart": "Add",
"viewCart": "View cart",
"cartTitle": "Your cart",
"placeOrder": "Place order",
"orderPlaced": "Order placed!",
"orderNumber": "Order #: {number}",
"orderHint": "Staff will prepare your order shortly",
"guestName": "Your name (optional)",
"guestPhone": "Mobile (optional)",
"addMoreItems": "Add more items",
"orderError": "Could not place order. Try again.",
"rateLimited": "Too many requests — please wait a few minutes",
"captchaRequired": "Please complete the security check",
"cafeUnavailable": "This café is temporarily unavailable",
"subtotal": "Total",
"searchPlaceholder": "Search menu...",
"allCategories": "All",
"searchNoResults": "No items match your search",
"clearSearch": "Clear search",
"emptyCategory": "No items in this category",
"view3d": "3D",
"view3dHint": "Drag to rotate — model spins live",
"close3d": "Close",
"emptyMenu": "This branch menu is empty or unavailable",
"guestQrBadge": "QR guest",
"tabMenu": "Menu",
"tabOrders": "My orders",
"myOrders": "Orders at this table",
"noOrders": "No orders yet",
"tracking": {
"back": "Back to menu",
"orderNumber": "Order number",
"table": "Table",
"loadError": "Could not load tracking",
"currentStep": "In progress",
"readyHint": "Your order is ready — pick it up at the counter or table",
"status": {
"pending": "Waiting for the café",
"seen": "Seen by staff",
"preparing": "Kitchen is preparing",
"ready": "Ready for pickup",
"done": "Delivered",
"cancelled": "Cancelled"
},
"steps": {
"submitted": "Order submitted",
"seen": "Seen by restaurant",
"preparing": "Preparing",
"ready": "Ready",
"done": "Completed",
"cancelled": "Cancelled"
}
}
},
"notifications": {
"title": "Notifications",
"empty": "No notifications",
"markAllRead": "Mark all read"
},
"reservations": {
"title": "Reservations",
"guest": "Guest",
"phone": "Phone",
"date": "Date",
"time": "Time",
"party": "Guests",
"table": "Table",
"tableOptional": "No specific table",
"tableNumber": "Table {number}",
"notes": "Notes",
"confirm": "Confirm",
"cancel": "Cancel",
"create": "Create reservation",
"newReservation": "Manual reservation",
"newReservationHint": "Pick table and time. When the guest arrives, use “Order & pay” at POS.",
"openPos": "Order & pay",
"markCompleted": "Mark completed",
"empty": "No reservations",
"status": {
"Pending": "Pending",
"Confirmed": "Confirmed",
"Cancelled": "Cancelled",
"Seated": "Seated",
"Completed": "Completed"
}
},
"branchesPage": {
"title": "Branches",
"subtitle": "Each branch has its own login mobile under the café master plan",
"listTitle": "Branch list",
"newName": "Branch name",
"loginPhone": "Branch login mobile",
"managerName": "Branch manager name",
"managerNamePlaceholder": "Optional — defaults to branch name",
"addSection": "New branch",
"add": "Add branch",
"empty": "No branches yet.",
"created": "Branch and login account created.",
"createError": "Could not add branch (duplicate phone or plan limit)",
"branchSelectHint": "Pick the active branch on POS and queue.",
"masterPlanHint": "Billing and taxes are managed only by the café owner.",
"ownerOnly": "Only the café owner can manage branches."
},
"subscription": {
"title": "Plan & billing",
"subtitle": "Current plan, usage, and upgrades",
"currentPlan": "Current plan",
"expires": "Expires",
"noExpiry": "—",
"refresh": "Refresh",
"ordersToday": "Orders today",
"customers": "Customers",
"smsUsage": "SMS this month",
"paymentSuccess": "Payment successful. Your plan was updated.",
"paymentFailed": "Payment failed.",
"loading": "Loading...",
"ownerOnly": "Only the café owner can manage billing. Branches use the master café plan.",
"paymentMethod": "Payment method",
"planExpired": "Subscription expired",
"featureMenu3d": "3D menu",
"featureDiscover": "Discover profile (AI)",
"featureOn": "Enabled",
"featureOff": "Not included — upgrade",
"featureMenu3dUpgrade": "3D menu is available on Pro and higher plans."
},
"settings": {
"title": "Settings",
"subtitle": "Shop profile, printers, and integrations",
"nav": {
"aria": "Settings menu",
"shop": "Shop & café",
"shopGeneral": "Profile & integrations",
"shopAppearance": "Appearance & colors",
"printer": "Printer",
"printerSettings": "Printer settings",
"printTest": "Print test page",
"shopDiscover": "Discover & AI"
},
"appearance": {
"paletteSection": "Color palette",
"paletteTitle": "Choose a preset palette",
"stylesSection": "UI style",
"stylesTitle": "Panel, menu & layout",
"panelStyle": "Dashboard panel style",
"menuStyle": "Menu display style",
"menuTexture": "QR menu background texture",
"guestMenuSection": "Table QR menu",
"guestMenuTitle": "Guest menu template",
"guestMenuDesc": "Guests scanning the table QR see this layout and background texture.",
"guestMenuPreviewHint": "Mobile preview (QR menu)",
"density": "Density",
"radius": "Corner radius",
"customSection": "Custom colors",
"customTitle": "Your café brand colors",
"customHint": "Leave empty to use the selected palette.",
"resetCustom": "Reset custom colors",
"previewSection": "Preview",
"previewTitle": "Panel & menu sample",
"previewNav": "Menu",
"previewItem": "Latte",
"previewCta": "Add",
"saved": "Appearance saved.",
"palettes": {
"meezi-green": "Meezi green",
"ocean-blue": "Ocean blue",
"royal-purple": "Royal purple",
"sunset-orange": "Sunset orange",
"rose-blush": "Rose blush",
"charcoal-gold": "Charcoal gold",
"espresso": "Espresso",
"forest": "Forest",
"midnight": "Midnight",
"coral": "Coral",
"gold-luxury": "Gold luxury",
"mint-fresh": "Mint fresh",
"wine-bar": "Wine bar",
"slate-modern": "Slate modern",
"cherry": "Cherry",
"teal-wave": "Teal wave",
"sand-cafe": "Sand café"
},
"panelStyles": {
"flat": "Flat",
"modern": "Modern",
"glass": "Glass",
"minimal": "Minimal",
"bold": "Bold",
"soft": "Soft",
"elevated": "Elevated",
"outline": "Outline"
},
"menuStyles": {
"cards": "Cards",
"compact": "Compact",
"grid": "Grid",
"list": "List",
"magazine": "Magazine",
"classic": "Classic"
},
"menuTextures": {
"none": "Plain",
"paper": "Paper",
"linen": "Linen",
"dots": "Dots",
"grid": "Grid",
"marble": "Marble",
"wood": "Wood",
"warm": "Warm café"
},
"densities": {
"compact": "Compact",
"comfortable": "Comfortable",
"spacious": "Spacious"
},
"radiusOptions": {
"none": "Sharp",
"sm": "Small",
"md": "Medium",
"lg": "Large",
"full": "Round"
},
"colors": {
"primary": "Primary",
"secondary": "Secondary",
"accent": "Accent / promo",
"background": "Background",
"surface": "Card / surface",
"text": "Text",
"textMuted": "Muted text",
"destructive": "Error / delete",
"success": "Success"
}
},
"snappfoodVendor": "Snappfood vendor ID",
"saveProfile": "Save profile",
"profile": {
"title": "Café profile",
"name": "Café name",
"city": "City",
"phone": "Phone",
"address": "Address",
"description": "Description",
"logo": "Logo",
"uploadLogo": "Upload logo",
"uploadCover": "Upload cover",
"saved": "Profile saved.",
"reloginHint": "Plan updated; sign out and in again if the badge looks wrong."
},
"taraz": "Taraz (tax system)",
"tarazHint": "Submit yesterday's invoices to Taraz (demo mode logs only).",
"tarazSubmit": "Submit to Taraz",
"tarazQueued": "Submission queued.",
"plans": {
"compareLabel": "Compare plans",
"compareHint": "Compare features and pick the right plan for your café.",
"featureColumn": "Features",
"popular": "Popular",
"current": "Current",
"perMonth": "/ month",
"freePrice": "Free",
"customPrice": "Contact us",
"unlimited": "Unlimited",
"included": "Included",
"currentPlanBtn": "Your plan",
"contactSales": "Contact sales",
"subscribe": "Get {plan}",
"names": {
"Free": "Free",
"Pro": "Pro",
"Business": "Business",
"Enterprise": "Enterprise"
},
"features": {
"ordersPerDay": "Orders per day",
"terminals": "POS terminals",
"crmCustomers": "CRM customers",
"smsPerMonth": "Marketing SMS",
"branches": "Branches",
"posKds": "POS & kitchen display",
"tablesQr": "Tables & QR ordering",
"menuReservations": "Menu & reservations",
"reports": "Reports",
"hrModule": "HR module",
"snappfoodDelivery": "Snappfood / delivery",
"tarazTax": "Taraz tax integration",
"badges": "Trust badges",
"whiteLabel": "White label",
"apiAccess": "Public API"
},
"levels": {
"basic": "Basic",
"full": "Full"
}
},
"discoverProfile": {
"title": "Discover & AI profile",
"subtitle": "Tags for matching guests to cafés",
"save": "Save",
"saved": "Saved",
"loading": "Loading..."
}
},
"support": {
"title": "Meezi support",
"subtitle": "Open a ticket for platform help",
"newTicket": "New ticket",
"subject": "Subject",
"message": "Your message",
"submit": "Submit ticket",
"myTickets": "My tickets",
"messages": "messages",
"created": "Ticket created",
"createFailed": "Could not create ticket",
"empty": "No tickets yet",
"loading": "Loading...",
"notFound": "Ticket not found",
"back": "Back",
"reply": "Your reply",
"send": "Send",
"replySent": "Reply sent",
"replyFailed": "Could not send reply",
"fromAdmin": "Meezi support",
"fromYou": "You",
"closedHint": "This ticket is closed — no new replies.",
"status": {
"open": "Open",
"inProgress": "In progress",
"waitingMerchant": "Awaiting your reply",
"resolved": "Resolved",
"closed": "Closed"
}
},
"admin": {
"nav": {
"title": "Platform admin",
"dashboard": "Dashboard",
"plans": "Plans & pricing",
"integrations": "Payments & SMS",
"notifications": "Notifications",
"settings": "App settings",
"features": "Features",
"cafes": "Cafes",
"tickets": "Tickets",
"logout": "Log out",
"websiteSection": "Website",
"websiteBlog": "Blog",
"websiteComments": "Comments",
"websiteDemoRequests": "Demo requests"
},
"website": {
"blogTitle": "Blog management",
"newPost": "New post",
"editPost": "Edit post",
"backToBlog": "Back to list",
"noPosts": "No posts yet",
"published": "Published",
"draft": "Draft",
"views": "views",
"commentsCount": "comment",
"edit": "Edit",
"save": "Save",
"saving": "Saving…",
"saved": "Saved",
"deleted": "Deleted",
"loading": "Loading…",
"fieldSlug": "Slug (URL)",
"fieldAuthor": "Author",
"fieldTitleFa": "Title (Persian)",
"fieldTitleEn": "Title (English)",
"fieldExcerptFa": "Excerpt (Persian)",
"fieldExcerptEn": "Excerpt (English)",
"fieldCategoryFa": "Category (Persian)",
"fieldCategoryEn": "Category (English)",
"fieldContentFa": "Content (Persian, Markdown)",
"fieldContentEn": "Content (English, Markdown)",
"fieldPublished": "Published",
"commentsTitle": "Comment management",
"noComments": "No comments found",
"approved": "Approved",
"pending": "Pending review",
"postSlug": "Post",
"commentApproved": "Comment approved",
"commentDeleted": "Comment deleted",
"filterComment_all": "All",
"filterComment_pending": "Pending",
"filterComment_approved": "Approved",
"demoRequestsTitle": "Demo requests",
"noDemoRequests": "No requests found",
"allStatuses": "All statuses",
"demoStatus_New": "New",
"demoStatus_Contacted": "Contacted",
"demoStatus_DemoScheduled": "Demo scheduled",
"demoStatus_Converted": "Converted",
"demoStatus_Rejected": "Rejected",
"errorGeneric": "An error occurred. Please try again."
},
"auth": {
"title": "System admin login",
"subtitle": "Authorized Meezi staff only",
"phone": "Phone",
"sendOtp": "Send code",
"otp": "Verification code",
"login": "Sign in",
"error": "Login failed",
"devHint": "In development the OTP is logged by Admin API (DEV admin OTP).",
"tabOtp": "One-time code",
"tabPassword": "Password",
"username": "Username",
"usernamePlaceholder": "Username",
"password": "Password",
"passwordPlaceholder": "Password",
"invalidCredentials": "Incorrect username or password."
},
"dashboard": {
"title": "Platform overview",
"totalCafes": "Total cafes",
"activeCafes": "Active",
"openTickets": "Open tickets",
"plans": "Plans configured"
},
"plans": {
"title": "Subscription plans",
"monthlyPrice": "Monthly price (Toman)",
"maxOrders": "Max orders per day",
"saved": "Plan saved"
},
"settings": {
"title": "Application settings",
"saved": "Saved"
},
"features": {
"title": "Feature flags",
"enabled": "On",
"disabled": "Off"
},
"cafes": {
"title": "Registered cafes",
"suspended": "Suspended",
"suspend": "Suspend",
"activate": "Activate",
"discoverProfile": {
"edit": "Discover profile",
"title": "Discover & AI profile",
"subtitle": "Tags for matching guests to cafés",
"save": "Save",
"saved": "Saved",
"loading": "Loading..."
}
},
"integrations": {
"title": "Payment gateways & Kavenegar",
"save": "Save settings",
"saved": "Settings saved",
"paymentTitle": "Payment gateways",
"kavenegarTitle": "Kavenegar (SMS)",
"active": "Active for billing",
"enabled": "Enabled",
"sandbox": "Sandbox mode",
"merchantId": "Merchant ID",
"apiKey": "API token",
"username": "Username",
"password": "Password",
"branchCode": "Branch code",
"terminalCode": "Terminal code (optional)",
"clientId": "Client ID",
"clientSecret": "Client Secret",
"baseUrl": "API base URL (optional)",
"taraHint": "Tara credit pay — API: api.tara-club.ir/club/api/v1 (login, trace, request, verify)",
"snappPayHint": "Snapp Pay BNPL — OAuth + payment token from Snapp Pay merchant panel",
"otpTemplate": "OTP template name (Kavenegar panel)",
"aiTitle": "Artificial intelligence",
"openAiTitle": "OpenAI",
"openAiHint": "Coffee advisor for guests — public API: POST /api/public/coffee-advisor",
"openAiApiKey": "OpenAI API key",
"openAiModel": "Model (e.g. gpt-4o-mini)",
"coffeeAdvisorEnabled": "Coffee advisor for guests",
"meshyTitle": "Meshy — menu 3D models",
"meshyHint": "Image-to-GLB for merchant menu (Business+). Get a key at meshy.ai.",
"meshyApiKey": "Meshy API key",
"menu3dEnabled": "3D generation from menu photos"
},
"notifications": {
"title": "Notification center",
"broadcastTitle": "Broadcast to all cafes",
"broadcastTitlePlaceholder": "Notification title",
"broadcastBodyPlaceholder": "Body (optional)",
"sendBroadcast": "Send to all",
"broadcastSent": "Sent to {count} cafes",
"allNotifications": "All notifications",
"empty": "No notifications yet"
},
"tickets": {
"title": "Support tickets",
"messages": "messages",
"loading": "Loading...",
"empty": "No tickets",
"notFound": "Ticket not found",
"back": "All tickets",
"replyPlaceholder": "Reply to merchant...",
"sendReply": "Send reply",
"replySent": "Reply sent",
"replyFailed": "Could not send reply",
"resolve": "Mark resolved",
"close": "Close ticket",
"statusUpdated": "Ticket status updated",
"closedHint": "Ticket is closed — replies disabled.",
"fromAdmin": "Meezi support",
"fromCafe": "Cafe",
"filter": {
"all": "All",
"open": "Open",
"closed": "Closed"
}
}
},
"errors": {
"planLimit": "Plan limit reached. Please upgrade.",
"notFound": "Not found",
"unauthorized": "Unauthorized",
"network": "Network error"
},
"discoverPublic": {
"brand": "Meezi",
"title": "Discover cafés",
"subtitle": "Find the right café in Tehran and Karaj",
"searchPlaceholder": "Search café name…",
"loading": "Loading…",
"empty": "No cafés match these filters",
"resultCount": "{count} cafés",
"applyFilters": "Apply filters",
"clearFilters": "Clear",
"viewCafe": "View café",
"backToList": "Back to list",
"notFound": "Café not found",
"exploreMore": "Explore more cafés",
"reviewCount": "{count} reviews",
"cities": { "tehran": "Tehran", "karaj": "Karaj" },
"sort": {
"rating": "Top rated",
"reviews": "Most reviews",
"name": "Name"
},
"filters": {
"themes": "Theme",
"vibes": "Vibe",
"occasions": "Good for",
"spaceFeatures": "Space",
"noise": "Noise",
"priceTier": "Price"
},
"openNowToggle": "Open now",
"openNowLabel": "Open now",
"closedLabel": "Closed",
"workingHoursTitle": "Working hours",
"websiteLabel": "Website",
"mapTitle": "Location",
"openInNeshan": "Open in Neshan Maps",
"reviewsTitle": "Guest reviews",
"ownerReply": "Owner's reply",
"coffeeAdvisor": {
"title": "Coffee advisor",
"subtitle": "Tell me about your mood — I'll suggest the perfect drink",
"placeholder": "e.g. I want something warm and not too sweet…",
"ask": "Get suggestion",
"loading": "Thinking…",
"error": "Could not get a suggestion. Try again."
},
"detectedFilters": "Detected filters",
"noResults": "No cafés found",
"galleryCount": "+{count} photos",
"days": {
"sat": "Saturday",
"sun": "Sunday",
"mon": "Monday",
"tue": "Tuesday",
"wed": "Wednesday",
"thu": "Thursday",
"fri": "Friday"
},
"sizes": {
"tiny": "Tiny",
"cozy": "Cozy",
"medium": "Medium",
"large": "Large",
"spacious": "Spacious"
},
"noiseLevels": {
"quiet": "Quiet",
"moderate": "Moderate",
"lively": "Lively"
},
"priceTiers": {
"budget": "Budget",
"mid": "Mid-range",
"premium": "Premium"
}
},
"cafePublicProfile": {
"title": "Public profile",
"subtitle": "What guests see on the discover page",
"loading": "Loading…",
"save": "Save",
"saved": "Saved",
"tabs": {
"info": "Info",
"gallery": "Gallery",
"hours": "Hours",
"social": "Social"
},
"description": "Description",
"descriptionPlaceholder": "Tell guests about your café…",
"gallery": "Gallery",
"galleryHint": "Upload up to 8 photos (JPEG, PNG, WebP, max 5 MB each)",
"noPhotos": "No photos uploaded yet",
"removePhoto": "Remove",
"uploadPhoto": "Upload photo",
"uploading": "Uploading…",
"uploadFailed": "Upload failed. Please try again.",
"galleryFull": "Gallery is full (max 8 photos).",
"workingHours": "Working hours",
"isOpen": "Open",
"instagram": "Instagram",
"instagramPlaceholder": "yourhandle",
"website": "Website",
"websitePlaceholder": "https://yourcafe.com",
"days": {
"sat": "Saturday",
"sun": "Sunday",
"mon": "Monday",
"tue": "Tuesday",
"wed": "Wednesday",
"thu": "Thursday",
"fri": "Friday"
}
},
"discoverProfile": {
"sections": {
"themes": "Theme & style",
"occasions": "Good for (multi)",
"spaceFeatures": "Space features",
"vibes": "Vibe",
"size": "Size",
"floors": "Floors",
"noiseLevel": "Noise",
"priceTier": "Price tier"
},
"hints": {
"themes": "For AI recommendations",
"occasions": "Dates, family, friends, meeting someone new…",
"spaceFeatures": "Indoor, outdoor, terrace, plants…",
"vibes": "Quiet, lively, romantic…"
},
"themes": {
"modern": "Modern",
"minimal": "Minimal",
"vintage": "Vintage",
"industrial": "Industrial",
"scandi": "Scandi",
"persian_traditional": "Persian traditional",
"book_cafe": "Book café",
"roastery": "Roastery",
"dessert_focus": "Dessert focus",
"brunch": "Brunch",
"late_night": "Late night",
"plants_heavy": "Plant-heavy",
"instagrammable": "Instagrammable",
"heritage": "Heritage",
"luxury": "Luxury",
"specialty_coffee": "Specialty coffee",
"tea_house": "Tea house",
"art_gallery": "Art gallery café",
"sport_cafe": "Sport café",
"gaming_cafe": "Gaming café"
},
"occasions": {
"date": "Date",
"family": "Family",
"friends": "Friends",
"finding_someone": "Meeting someone new",
"solo": "Solo",
"business_meeting": "Business",
"study_work": "Study & work",
"celebration": "Celebration",
"quick_coffee": "Quick coffee",
"breakfast": "Breakfast",
"brunch": "Brunch",
"after_dinner": "After dinner",
"group_large": "Large group"
},
"spaceFeatures": {
"indoor": "Indoor",
"outdoor": "Outdoor",
"terrace": "Terrace",
"rooftop": "Rooftop",
"garden": "Garden",
"plants": "Plants",
"wifi": "WiFi",
"parking": "Parking",
"wheelchair": "Wheelchair access",
"kids_friendly": "Kid-friendly",
"pet_friendly": "Pet-friendly",
"smoking_area": "Smoking area",
"live_music": "Live music",
"private_room": "Private room",
"counter_only": "Counter only",
"takeaway": "Takeaway",
"hookah": "Hookah",
"board_games": "Board games",
"no_smoking": "Non-smoking",
"prayer_room": "Prayer room"
},
"vibes": {
"quiet": "Quiet",
"lively": "Lively",
"romantic": "Romantic",
"cozy": "Cozy",
"trendy": "Trendy",
"traditional": "Traditional",
"artistic": "Artistic",
"luxury": "Luxury",
"casual": "Casual",
"study_friendly": "Study-friendly"
},
"sizes": {
"tiny": "Tiny",
"cozy": "Cozy",
"medium": "Medium",
"large": "Large",
"spacious": "Spacious"
},
"floors": {
"one": "1 floor",
"two": "2 floors",
"three": "3 floors",
"multi": "Multi-floor"
},
"noiseLevels": {
"quiet": "Quiet",
"moderate": "Moderate",
"lively": "Lively"
},
"priceTiers": {
"budget": "Budget",
"mid": "Mid",
"premium": "Premium"
}
}
}