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; text-align: left;
} }
.metaRow {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-top: auto;
min-width: 0;
}
.categoryChip { .categoryChip {
display: inline-block; display: inline-block;
align-self: flex-start; max-width: 60%;
max-width: 100%;
padding: 3px 10px; padding: 3px 10px;
font-family: var(--font-ui); font-family: var(--font-ui);
font-size: 11px; font-size: 11px;
@@ -131,15 +139,14 @@
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} flex-shrink: 1;
.meta {
margin: 0;
font-size: 12px;
line-height: 1.4;
color: var(--text-muted);
} }
.metaDate { .metaDate {
flex-shrink: 0;
font-size: 12px;
line-height: 1.4;
color: var(--text-muted);
unicode-bidi: isolate; unicode-bidi: isolate;
text-align: right;
} }
@@ -94,16 +94,18 @@ export function PortfolioCard({
</p> </p>
) )
) : null} ) : null}
<div className={cardStyles.metaRow} dir="ltr">
{portfolio.categoryName ? ( {portfolio.categoryName ? (
<span className={cardStyles.categoryChip} dir="auto"> <span className={cardStyles.categoryChip} dir="auto">
{portfolio.categoryName} {portfolio.categoryName}
</span> </span>
) : null} ) : (
<p className={cardStyles.meta}> <span />
)}
<span className={cardStyles.metaDate} dir="auto"> <span className={cardStyles.metaDate} dir="auto">
{publishDate} {publishDate}
</span> </span>
</p> </div>
</div> </div>
</Link> </Link>
+4 -4
View File
@@ -1388,13 +1388,13 @@ const en = {
'portfolio.list.errorDelete': 'Unable to delete portfolio.', 'portfolio.list.errorDelete': 'Unable to delete portfolio.',
'portfolio.list.errorMove': 'Unable to move portfolio.', 'portfolio.list.errorMove': 'Unable to move portfolio.',
'portfolio.list.toast.removed': 'Portfolio removed.', '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.deleteTitle': 'Delete Portfolio',
'portfolio.list.deleteMessage': 'portfolio.list.deleteMessage':
'Are you sure you want to delete "{name}"? This action cannot be undone.', 'Are you sure you want to delete "{name}"? This action cannot be undone.',
'portfolio.list.addNew': 'Add new portfolio', 'portfolio.list.addNew': 'Add new portfolio',
'portfolio.card.moveUp': 'Move up', 'portfolio.card.moveUp': 'Move to top',
'portfolio.card.edit': 'Edit portfolio', 'portfolio.card.edit': 'Edit portfolio',
'portfolio.card.comments': 'View comments', 'portfolio.card.comments': 'View comments',
'portfolio.card.remove': 'Remove portfolio', 'portfolio.card.remove': 'Remove portfolio',
@@ -3568,13 +3568,13 @@ const fa: Record<MessageKey, string> = {
'portfolio.list.errorDelete': 'حذف نمونه کار ممکن نشد.', 'portfolio.list.errorDelete': 'حذف نمونه کار ممکن نشد.',
'portfolio.list.errorMove': 'جابه‌جایی نمونه کار ممکن نشد.', 'portfolio.list.errorMove': 'جابه‌جایی نمونه کار ممکن نشد.',
'portfolio.list.toast.removed': 'نمونه کار حذف شد.', 'portfolio.list.toast.removed': 'نمونه کار حذف شد.',
'portfolio.list.toast.movedUp': 'نمونه کار به بالا منتقل شد.', 'portfolio.list.toast.movedUp': 'نمونه کار به ابتدای لیست منتقل شد.',
'portfolio.list.deleteTitle': 'حذف نمونه کار', 'portfolio.list.deleteTitle': 'حذف نمونه کار',
'portfolio.list.deleteMessage': 'portfolio.list.deleteMessage':
'آیا از حذف «{name}» مطمئن هستید؟ این عمل قابل بازگشت نیست.', 'آیا از حذف «{name}» مطمئن هستید؟ این عمل قابل بازگشت نیست.',
'portfolio.list.addNew': 'افزودن نمونه کار', 'portfolio.list.addNew': 'افزودن نمونه کار',
'portfolio.card.moveUp': 'انتقال به بالا', 'portfolio.card.moveUp': 'انتقال به ابتدا',
'portfolio.card.edit': 'ویرایش نمونه کار', 'portfolio.card.edit': 'ویرایش نمونه کار',
'portfolio.card.comments': 'مشاهده نظرات', 'portfolio.card.comments': 'مشاهده نظرات',
'portfolio.card.remove': 'حذف نمونه کار', 'portfolio.card.remove': 'حذف نمونه کار',
+9 -13
View File
@@ -177,23 +177,19 @@ export function PortfolioListPage() {
if (index === 0 && currentPage === 1) return if (index === 0 && currentPage === 1) return
const current = portfolios[index] 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) setMovingUpId(id)
setError('') setError('')
try { try {
if (index === 0) { await updatePortfolio(current.id, { sortOrder: nextSortOrder })
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 }),
])
}
}
showToast(t('portfolio.list.toast.movedUp'), 'success') showToast(t('portfolio.list.toast.movedUp'), 'success')
await loadPortfolios(currentPage) await loadPortfolios(currentPage)
} catch (err) { } catch (err) {