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
+35 -7
View File
@@ -2,6 +2,7 @@ import { Link } from 'react-router-dom'
import { Pencil, MessageSquare, Trash2 } from 'lucide-react'
import type { Portfolio } from '../types/portfolio'
import { formatPortfolioCardDate } from '../services/portfolioService'
import { textLocaleAttrs } from '../utils/textLocale'
import { Tooltip } from './Tooltip'
import cardStyles from './PortfolioCard.module.css'
import controlStyles from './ProductCard.module.css'
@@ -22,6 +23,12 @@ export function PortfolioCard({
onRemove,
}: PortfolioCardProps) {
const publishDate = formatPortfolioCardDate(portfolio.publishedAt ?? portfolio.createdAt)
const titleFa = (portfolio.titleFa || portfolio.title || '').trim()
const titleEn = (portfolio.titleEn || '').trim()
const showBothTitles = Boolean(titleFa && titleEn)
const showAbstract = !showBothTitles
const abstractLocale = textLocaleAttrs(portfolio.abstract)
const hasAbstract = Boolean(portfolio.abstract?.trim())
return (
<article className={cardStyles.card}>
@@ -30,7 +37,7 @@ export function PortfolioCard({
{portfolio.titleImageUrl ? (
<img
src={portfolio.titleImageUrl}
alt={portfolio.title}
alt={titleFa || titleEn || 'Portfolio'}
className={cardStyles.image}
loading="lazy"
/>
@@ -40,12 +47,33 @@ export function PortfolioCard({
</div>
<div className={cardStyles.body}>
<h3 className={cardStyles.title}>{portfolio.title}</h3>
{portfolio.abstract ? (
<p className={cardStyles.abstract}>{portfolio.abstract}</p>
) : (
<p className={cardStyles.abstract}>No summary yet.</p>
)}
{titleFa ? (
<h3 className={`${cardStyles.titleFa} faText`} lang="fa" dir="rtl">
{titleFa}
</h3>
) : null}
{titleEn ? (
<p className={cardStyles.titleEn} lang="en" dir="ltr">
{titleEn}
</p>
) : null}
{showAbstract ? (
hasAbstract ? (
<p
className={[cardStyles.abstract, abstractLocale.className]
.filter(Boolean)
.join(' ')}
lang={abstractLocale.lang}
dir={abstractLocale.dir}
>
{portfolio.abstract}
</p>
) : (
<p className={cardStyles.abstract} lang="en" dir="ltr">
No summary yet.
</p>
)
) : null}
<p className={cardStyles.meta}>
{portfolio.categoryName ? (
<>