Add portfolio website link field and card open-link control.

Stay on the current list page after move-to-top; only toast success.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-23 16:46:13 +03:30
co-authored by Cursor
parent 85524544ca
commit c289de5d2e
7 changed files with 76 additions and 7 deletions
@@ -13,6 +13,7 @@ export interface PortfolioApi {
titleEn: string | null
slug: string
abstract: string
projectUrl: string | null
mainTextHtml: string
status: PortfolioStatus
categoryId: string | null
@@ -58,6 +59,7 @@ export interface CreatePortfolioPayload {
/** @deprecated Prefer titleFa */
title?: string
abstract?: string
projectUrl?: string
mainTextHtml?: string
categoryId?: string
status?: PortfolioStatus
@@ -73,6 +75,7 @@ export interface UpdatePortfolioPayload {
/** @deprecated Prefer titleFa */
title?: string
abstract?: string | null
projectUrl?: string | null
mainTextHtml?: string | null
categoryId?: string | null
status?: PortfolioStatus
@@ -94,6 +97,13 @@ export function resolvePortfolioTitleImageUrl(portfolio: PortfolioApi): string |
return extractFirstImageUrl(portfolio.mainTextHtml) || null
}
export function resolvePortfolioExternalUrl(url: string | null | undefined): string | null {
const trimmed = url?.trim()
if (!trimmed) return null
if (/^https?:\/\//i.test(trimmed)) return trimmed
return `https://${trimmed}`
}
export function mapPortfolioApiToUi(portfolio: PortfolioApi): Portfolio {
return {
id: portfolio.id,
@@ -102,6 +112,7 @@ export function mapPortfolioApiToUi(portfolio: PortfolioApi): Portfolio {
titleEn: portfolio.titleEn ?? null,
slug: portfolio.slug,
abstract: portfolio.abstract,
projectUrl: portfolio.projectUrl?.trim() || null,
status: portfolio.status,
categoryId: portfolio.categoryId,
categoryName: portfolio.categoryName,
@@ -157,6 +168,7 @@ export function mapPortfolioApiToFormState(portfolio: PortfolioApi) {
titleEn: portfolio.titleEn ?? '',
abstract: portfolio.abstract,
mainTextHtml: portfolio.mainTextHtml,
projectUrl: portfolio.projectUrl?.trim() || '',
categoryId: portfolio.categoryId ?? '',
tags: portfolio.tags,
titleImage: resolvePortfolioTitleImageUrl(portfolio),