Fix portfolio move-to-top and put category beside the date.

Bump sort_order above the page leader instead of swapping, and align category left with date right on one meta row.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-23 15:12:45 +03:30
co-authored by Cursor
parent 1e9f6481b0
commit be9e7da424
4 changed files with 38 additions and 33 deletions
@@ -115,10 +115,18 @@
text-align: left;
}
.metaRow {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-top: auto;
min-width: 0;
}
.categoryChip {
display: inline-block;
align-self: flex-start;
max-width: 100%;
max-width: 60%;
padding: 3px 10px;
font-family: var(--font-ui);
font-size: 11px;
@@ -131,15 +139,14 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.meta {
margin: 0;
font-size: 12px;
line-height: 1.4;
color: var(--text-muted);
flex-shrink: 1;
}
.metaDate {
flex-shrink: 0;
font-size: 12px;
line-height: 1.4;
color: var(--text-muted);
unicode-bidi: isolate;
text-align: right;
}
@@ -94,16 +94,18 @@ export function PortfolioCard({
</p>
)
) : null}
{portfolio.categoryName ? (
<span className={cardStyles.categoryChip} dir="auto">
{portfolio.categoryName}
</span>
) : null}
<p className={cardStyles.meta}>
<div className={cardStyles.metaRow} dir="ltr">
{portfolio.categoryName ? (
<span className={cardStyles.categoryChip} dir="auto">
{portfolio.categoryName}
</span>
) : (
<span />
)}
<span className={cardStyles.metaDate} dir="auto">
{publishDate}
</span>
</p>
</div>
</div>
</Link>
+4 -4
View File
@@ -1388,13 +1388,13 @@ const en = {
'portfolio.list.errorDelete': 'Unable to delete portfolio.',
'portfolio.list.errorMove': 'Unable to move portfolio.',
'portfolio.list.toast.removed': 'Portfolio removed.',
'portfolio.list.toast.movedUp': 'Portfolio moved up.',
'portfolio.list.toast.movedUp': 'Portfolio moved to top.',
'portfolio.list.deleteTitle': 'Delete Portfolio',
'portfolio.list.deleteMessage':
'Are you sure you want to delete "{name}"? This action cannot be undone.',
'portfolio.list.addNew': 'Add new portfolio',
'portfolio.card.moveUp': 'Move up',
'portfolio.card.moveUp': 'Move to top',
'portfolio.card.edit': 'Edit portfolio',
'portfolio.card.comments': 'View comments',
'portfolio.card.remove': 'Remove portfolio',
@@ -3568,13 +3568,13 @@ const fa: Record<MessageKey, string> = {
'portfolio.list.errorDelete': 'حذف نمونه کار ممکن نشد.',
'portfolio.list.errorMove': 'جابه‌جایی نمونه کار ممکن نشد.',
'portfolio.list.toast.removed': 'نمونه کار حذف شد.',
'portfolio.list.toast.movedUp': 'نمونه کار به بالا منتقل شد.',
'portfolio.list.toast.movedUp': 'نمونه کار به ابتدای لیست منتقل شد.',
'portfolio.list.deleteTitle': 'حذف نمونه کار',
'portfolio.list.deleteMessage':
'آیا از حذف «{name}» مطمئن هستید؟ این عمل قابل بازگشت نیست.',
'portfolio.list.addNew': 'افزودن نمونه کار',
'portfolio.card.moveUp': 'انتقال به بالا',
'portfolio.card.moveUp': 'انتقال به ابتدا',
'portfolio.card.edit': 'ویرایش نمونه کار',
'portfolio.card.comments': 'مشاهده نظرات',
'portfolio.card.remove': 'حذف نمونه کار',
+9 -13
View File
@@ -177,23 +177,19 @@ export function PortfolioListPage() {
if (index === 0 && currentPage === 1) return
const current = portfolios[index]
// Jump above the current page leader (highest sort_order wins). Avoids
// fragile swaps that no-op when ties / secondary date order disagree.
const leader = portfolios[0]
const nextSortOrder =
index === 0
? current.sortOrder + 1
: Math.max(leader.sortOrder, current.sortOrder) + 1
setMovingUpId(id)
setError('')
try {
if (index === 0) {
await updatePortfolio(current.id, { sortOrder: current.sortOrder + 1 })
} else {
const previous = portfolios[index - 1]
if (current.sortOrder === previous.sortOrder) {
await updatePortfolio(current.id, { sortOrder: previous.sortOrder + 1 })
} else {
await Promise.all([
updatePortfolio(current.id, { sortOrder: previous.sortOrder }),
updatePortfolio(previous.id, { sortOrder: current.sortOrder }),
])
}
}
await updatePortfolio(current.id, { sortOrder: nextSortOrder })
showToast(t('portfolio.list.toast.movedUp'), 'success')
await loadPortfolios(currentPage)
} catch (err) {