Improve product cards/pagination, Farsi locale fonts, and super-admin migrate UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-07-29 16:10:43 +03:30
co-authored by Cursor
parent 2e40d5eb4c
commit f5b2193ba1
108 changed files with 2421 additions and 812 deletions
+41 -50
View File
@@ -4,6 +4,7 @@ import { AddCustomerModal } from '../components/AddCustomerModal'
import { Breadcrumbs } from '../components/Breadcrumbs'
import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal'
import { EditCustomerModal } from '../components/EditCustomerModal'
import { Pagination } from '../components/Pagination'
import { ToggleSwitch } from '../components/ToggleSwitch'
import { Tooltip } from '../components/Tooltip'
import { useToast } from '../context/ToastContext'
@@ -17,6 +18,7 @@ import {
type CustomersListResponse,
} from '../services/customerService'
import { formatIrtPrice } from '../utils/irtPrice'
import { textLocaleAttrs } from '../utils/textLocale'
import filterStyles from '../components/ListFiltersPanel.module.css'
import pageStyles from '../components/PageContent.module.css'
import styles from './CustomersPage.module.css'
@@ -30,14 +32,6 @@ function formatDate(value: string) {
return d.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: '2-digit' })
}
function buildPageNumbers(page: number, totalPages: number) {
const start = Math.max(1, page - 2)
const end = Math.min(totalPages, page + 2)
const numbers: number[] = []
for (let i = start; i <= end; i++) numbers.push(i)
return numbers
}
function displayName(customer: BusinessCustomerListItem) {
const name = [customer.firstName, customer.lastName].filter(Boolean).join(' ').trim()
return name || '—'
@@ -112,8 +106,6 @@ export function CustomersPage() {
return Math.max(1, Math.ceil(total / PAGE_SIZE))
}, [data?.total])
const pageNumbers = useMemo(() => buildPageNumbers(page, totalPages), [page, totalPages])
const showingFrom = useMemo(() => {
if (!data || data.total === 0) return 0
return (page - 1) * PAGE_SIZE + 1
@@ -365,7 +357,24 @@ export function CustomersPage() {
className={!customer.isEnabled ? styles.inactiveRow : undefined}
>
<td className={styles.td}>
<div className={styles.customerName}>{displayName(customer)}</div>
{(() => {
const name = displayName(customer)
const locale = textLocaleAttrs(name)
return (
<div
className={[
styles.customerName,
locale.className,
]
.filter(Boolean)
.join(' ')}
lang={locale.lang}
dir={locale.dir}
>
{name}
</div>
)
})()}
{!customer.isEnabled && (
<div className={styles.statusDisabled}>Disabled</div>
)}
@@ -383,15 +392,19 @@ export function CustomersPage() {
</td>
<td className={`${styles.td} ${styles.tdActions}`}>
<div className={styles.rowActions}>
<span className={styles.toggleInActions}>
<ToggleSwitch
checked={customer.isEnabled}
disabled={togglingId === customer.id || removing}
size="compact"
ariaLabel={`${customer.isEnabled ? 'Disable' : 'Enable'} ${displayName(customer)}`}
onChange={(isEnabled) => void handleToggleEnabled(customer, isEnabled)}
/>
</span>
<Tooltip
label={`${customer.isEnabled ? 'Disable' : 'Enable'} customer`}
>
<span className={styles.toggleInActions}>
<ToggleSwitch
checked={customer.isEnabled}
disabled={togglingId === customer.id || removing}
size="compact"
ariaLabel={`${customer.isEnabled ? 'Disable' : 'Enable'} ${displayName(customer)}`}
onChange={(isEnabled) => void handleToggleEnabled(customer, isEnabled)}
/>
</span>
</Tooltip>
<Tooltip label="Edit customer">
<button
type="button"
@@ -442,37 +455,15 @@ export function CustomersPage() {
<div className={styles.pagination}>
<div>
Page {page} / {totalPages}
</div>
<div className={styles.pagerBtns}>
<button
type="button"
className={styles.pageBtn}
onClick={() => setPage((p) => Math.max(1, p - 1))}
disabled={page <= 1 || loading}
>
Prev
</button>
{pageNumbers.map((n) => (
<button
key={n}
type="button"
className={`${styles.pageBtn} ${n === page ? styles.pageBtnActive : ''}`}
onClick={() => setPage(n)}
disabled={loading}
>
{n}
</button>
))}
<button
type="button"
className={styles.pageBtn}
onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
disabled={page >= totalPages || loading}
>
Next
</button>
Page {page} / {totalPages} · {PAGE_SIZE} per page · {data?.total ?? 0} total
</div>
<Pagination
currentPage={page}
totalPages={totalPages}
onPageChange={setPage}
disabled={loading}
variant="inline"
/>
</div>
</div>
</div>