Add FA/EN locale, home activity charts, and theme-aware polish.
Ship shared LocaleProvider, business/customer i18n, branding defaultLocale, curated home tiles with dual 30-day charts, and chart/page aura tokens; refresh PROJECT_CONTEXT. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
f5b2193ba1
commit
66004a0fba
@@ -12,6 +12,7 @@ import {
|
||||
PORTFOLIOS_PER_PAGE,
|
||||
deletePortfolio,
|
||||
listPortfolios,
|
||||
updatePortfolio,
|
||||
} from '../services/portfolioService'
|
||||
import type { Portfolio } from '../types/portfolio'
|
||||
import pageStyles from '../components/PageContent.module.css'
|
||||
@@ -25,6 +26,7 @@ export function PortfolioListPage() {
|
||||
const [currentPage, setCurrentPage] = useState(1)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [isDeleting, setIsDeleting] = useState(false)
|
||||
const [movingUpId, setMovingUpId] = useState<string | null>(null)
|
||||
const [error, setError] = useState('')
|
||||
const [commentCounts, setCommentCounts] = useState<Record<string, number>>({})
|
||||
const [deleteTarget, setDeleteTarget] = useState<{ id: string; title: string } | null>(null)
|
||||
@@ -81,6 +83,43 @@ export function PortfolioListPage() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleMoveUp(id: string) {
|
||||
const index = portfolios.findIndex((item) => item.id === id)
|
||||
if (index < 0) return
|
||||
if (index === 0 && currentPage === 1) return
|
||||
|
||||
const current = portfolios[index]
|
||||
setMovingUpId(id)
|
||||
setError('')
|
||||
|
||||
try {
|
||||
if (index === 0) {
|
||||
// First on this page, but not global first — bump above the current band.
|
||||
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('Portfolio moved up.', 'success')
|
||||
await loadPortfolios(currentPage)
|
||||
} catch (err) {
|
||||
if (err instanceof ApiError) {
|
||||
setError(err.message)
|
||||
} else {
|
||||
setError('Unable to move portfolio.')
|
||||
}
|
||||
} finally {
|
||||
setMovingUpId(null)
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmDelete() {
|
||||
if (!deleteTarget) return
|
||||
|
||||
@@ -152,11 +191,14 @@ export function PortfolioListPage() {
|
||||
) : (
|
||||
<>
|
||||
<div className={pageStyles.gridCols4}>
|
||||
{portfolios.map((portfolio) => (
|
||||
{portfolios.map((portfolio, index) => (
|
||||
<PortfolioCard
|
||||
key={portfolio.id}
|
||||
portfolio={portfolio}
|
||||
commentCount={commentCounts[portfolio.id] ?? portfolio.commentCount}
|
||||
canMoveUp={!(index === 0 && currentPage === 1)}
|
||||
isMovingUp={movingUpId === portfolio.id}
|
||||
onMoveUp={handleMoveUp}
|
||||
onEdit={handleEdit}
|
||||
onComments={handleComments}
|
||||
onRemove={handleRemoveRequest}
|
||||
|
||||
Reference in New Issue
Block a user