Localize order modals, add dual logos, and improve admin order tools.
Farsi business order/variation UI, light/dark logo upload on business profile, payment order steps, variation editing, super-admin site links, and checkout/auth fixes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
dc570c1e7f
commit
5e799eddf9
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import { X } from 'lucide-react'
|
||||
import { useT } from '../i18n/useT'
|
||||
import type { Order } from '../services/orderService'
|
||||
import { formatCellForDisplay } from '../lib/cellNumber'
|
||||
import { formatIrtPrice } from '../utils/irtPrice'
|
||||
@@ -30,6 +31,7 @@ function totalQuantity(order: Order) {
|
||||
}
|
||||
|
||||
export function OrderItemsModal({ open, order, onClose }: OrderItemsModalProps) {
|
||||
const t = useT()
|
||||
const [mounted, setMounted] = useState(open)
|
||||
const [closing, setClosing] = useState(false)
|
||||
|
||||
@@ -75,11 +77,16 @@ export function OrderItemsModal({ open, order, onClose }: OrderItemsModalProps)
|
||||
<div className={modalStyles.header}>
|
||||
<div>
|
||||
<h2 id="order-items-title" className={modalStyles.title}>
|
||||
Order items
|
||||
{t('orderItems.title')}
|
||||
</h2>
|
||||
<p className={modalStyles.subtitle}>{order.orderNumber}</p>
|
||||
</div>
|
||||
<button type="button" className={modalStyles.closeBtn} onClick={onClose} aria-label="Close">
|
||||
<button
|
||||
type="button"
|
||||
className={modalStyles.closeBtn}
|
||||
onClick={onClose}
|
||||
aria-label={t('orderItems.close')}
|
||||
>
|
||||
<X size={18} />
|
||||
</button>
|
||||
</div>
|
||||
@@ -87,26 +94,27 @@ export function OrderItemsModal({ open, order, onClose }: OrderItemsModalProps)
|
||||
<div className={`${modalStyles.body} ${styles.body}`}>
|
||||
<div className={styles.metaRow}>
|
||||
<span className={styles.metaItem}>
|
||||
Customer: <strong>{displayName(order)}</strong>
|
||||
{t('orderItems.customer')}: <strong>{displayName(order)}</strong>
|
||||
</span>
|
||||
<span className={styles.metaItem}>
|
||||
Phone: <strong>{formatCellForDisplay(order.customer.cellNumber)}</strong>
|
||||
{t('orderItems.phone')}:{' '}
|
||||
<strong>{formatCellForDisplay(order.customer.cellNumber)}</strong>
|
||||
</span>
|
||||
<span className={styles.metaItem}>
|
||||
Items: <strong>{itemCount}</strong>
|
||||
{t('orderItems.items')}: <strong>{itemCount}</strong>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{order.items.length === 0 ? (
|
||||
<p className={styles.empty}>No items in this order.</p>
|
||||
<p className={styles.empty}>{t('orderItems.empty')}</p>
|
||||
) : (
|
||||
<div className={styles.tableBlock}>
|
||||
<div className={styles.tableHead}>
|
||||
<span aria-hidden="true" />
|
||||
<span>Product</span>
|
||||
<span>Qty</span>
|
||||
<span>Unit price</span>
|
||||
<span>Line total</span>
|
||||
<span>{t('orderItems.product')}</span>
|
||||
<span>{t('orderItems.qty')}</span>
|
||||
<span>{t('orderItems.unitPrice')}</span>
|
||||
<span>{t('orderItems.lineTotal')}</span>
|
||||
</div>
|
||||
<ul className={styles.itemList}>
|
||||
{order.items.map((item) => (
|
||||
@@ -122,7 +130,9 @@ export function OrderItemsModal({ open, order, onClose }: OrderItemsModalProps)
|
||||
<div className={styles.itemTitle}>{item.productTitle}</div>
|
||||
<div className={styles.itemVariant}>{formatVariantLabel(item.selections)}</div>
|
||||
{item.variantSku && (
|
||||
<div className={styles.itemSku}>SKU: {item.variantSku}</div>
|
||||
<div className={styles.itemSku}>
|
||||
{t('orderItems.sku', { sku: item.variantSku })}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.qtyCell}>{item.quantity}</div>
|
||||
@@ -136,20 +146,23 @@ export function OrderItemsModal({ open, order, onClose }: OrderItemsModalProps)
|
||||
|
||||
<div className={styles.summary}>
|
||||
<span className={styles.summaryLabel}>
|
||||
Order total · {itemCount} {itemCount === 1 ? 'item' : 'items'}
|
||||
{t('orderItems.summary', {
|
||||
count: itemCount,
|
||||
itemsLabel:
|
||||
itemCount === 1 ? t('orderItems.item') : t('orderItems.itemsPlural'),
|
||||
})}
|
||||
</span>
|
||||
<span className={styles.summaryValue}>{formatIrtPrice(order.total)}</span>
|
||||
</div>
|
||||
|
||||
<div className={modalStyles.actions}>
|
||||
<button type="button" className={modalStyles.cancelBtn} onClick={onClose}>
|
||||
Close
|
||||
{t('orderItems.close')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
,
|
||||
document.body,
|
||||
</div>,
|
||||
document.body,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user