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
@@ -7,6 +7,12 @@
padding-top: 24px;
}
.paginationInline {
margin-top: 0;
padding-top: 0;
justify-content: flex-end;
}
.navBtn {
width: 38px;
height: 38px;
@@ -49,11 +55,16 @@
transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.pageBtn:hover {
.pageBtn:hover:not(:disabled) {
background: rgba(var(--primary-rgb) / 0.08);
color: var(--primary);
}
.pageBtn:disabled {
opacity: 0.55;
cursor: not-allowed;
}
.pageBtn.active {
background: var(--primary);
border-color: var(--primary);
@@ -1,11 +1,31 @@
import { ChevronLeft, ChevronRight } from 'lucide-react'
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react'
import styles from './Pagination.module.css'
interface PaginationProps {
export interface PaginationProps {
currentPage: number
totalPages: number
onPageChange: (page: number) => void
ariaLabel?: string
/** Pages on each side of current. Default 3 → e.g. 1 2 3 [4] 5 6 7 */
siblingCount?: number
disabled?: boolean
/** `inline` for table footers (no top margin). */
variant?: 'default' | 'inline'
className?: string
}
function buildPageWindow(
currentPage: number,
totalPages: number,
siblingCount: number,
): number[] {
const start = Math.max(1, currentPage - siblingCount)
const end = Math.min(totalPages, currentPage + siblingCount)
const pages: number[] = []
for (let page = start; page <= end; page += 1) {
pages.push(page)
}
return pages
}
export function Pagination({
@@ -13,18 +33,39 @@ export function Pagination({
totalPages,
onPageChange,
ariaLabel = 'Pagination',
siblingCount = 3,
disabled = false,
variant = 'default',
className,
}: PaginationProps) {
if (totalPages <= 1) return null
const pages = Array.from({ length: totalPages }, (_, i) => i + 1)
const pages = buildPageWindow(currentPage, totalPages, siblingCount)
const rootClass = [
styles.pagination,
variant === 'inline' ? styles.paginationInline : '',
className ?? '',
]
.filter(Boolean)
.join(' ')
return (
<nav className={styles.pagination} aria-label={ariaLabel}>
<nav className={rootClass} aria-label={ariaLabel}>
<button
type="button"
className={styles.navBtn}
onClick={() => onPageChange(1)}
disabled={disabled || currentPage === 1}
aria-label="First page"
>
<ChevronsLeft size={18} />
</button>
<button
type="button"
className={styles.navBtn}
onClick={() => onPageChange(currentPage - 1)}
disabled={currentPage === 1}
disabled={disabled || currentPage === 1}
aria-label="Previous page"
>
<ChevronLeft size={18} />
@@ -37,6 +78,7 @@ export function Pagination({
type="button"
className={`${styles.pageBtn} ${page === currentPage ? styles.active : ''}`}
onClick={() => onPageChange(page)}
disabled={disabled}
aria-label={`Page ${page}`}
aria-current={page === currentPage ? 'page' : undefined}
>
@@ -49,11 +91,21 @@ export function Pagination({
type="button"
className={styles.navBtn}
onClick={() => onPageChange(currentPage + 1)}
disabled={currentPage === totalPages}
disabled={disabled || currentPage === totalPages}
aria-label="Next page"
>
<ChevronRight size={18} />
</button>
<button
type="button"
className={styles.navBtn}
onClick={() => onPageChange(totalPages)}
disabled={disabled || currentPage === totalPages}
aria-label="Last page"
>
<ChevronsRight size={18} />
</button>
</nav>
)
}
@@ -1,4 +1,5 @@
import { useEffect, useState, type FormEvent } from 'react'
import { createPortal } from 'react-dom'
import { X } from 'lucide-react'
import styles from './PasswordResetModal.module.css'
@@ -153,7 +154,7 @@ export function PasswordResetModal({
if (!mounted) return null
return (
return createPortal(
<div
className={`${styles.overlay} ${closing ? styles.overlayOut : styles.overlayIn}`}
onClick={onClose}
@@ -278,6 +279,7 @@ export function PasswordResetModal({
</div>
</form>
</div>
</div>
</div>,
document.body,
)
}
+1
View File
@@ -10,6 +10,7 @@ export {
} from './components/AddressListEditor'
export { Breadcrumbs, type BreadcrumbItem } from './components/Breadcrumbs'
export { Pagination } from './components/Pagination'
export type { PaginationProps } from './components/Pagination'
export { SectionCard } from './components/SectionCard'
export { RouteLoader } from './components/RouteLoader'
export { createDomainGuard, type DomainGuardConfig } from './components/createDomainGuard'