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
+18 -2
View File
@@ -1,8 +1,11 @@
import { Link } from 'react-router-dom'
import { ChevronUp, Pencil, MessageSquare, Trash2 } from 'lucide-react'
import { ChevronUp, Link2, Pencil, MessageSquare, Trash2 } from 'lucide-react'
import { useLocale } from '@meshkee/dashboard-ui'
import type { Portfolio } from '../types/portfolio'
import { formatPortfolioCardDate } from '../services/portfolioService'
import {
formatPortfolioCardDate,
resolvePortfolioExternalUrl,
} from '../services/portfolioService'
import { useT } from '../i18n/useT'
import { textLocaleAttrs } from '../utils/textLocale'
import { Tooltip } from './Tooltip'
@@ -45,6 +48,7 @@ export function PortfolioCard({
const hasAbstract = Boolean(portfolio.abstract?.trim())
// In FA UI, keep cards RTL even when EN titles/abstracts are shown.
const abstractDir = isFa ? 'rtl' : abstractLocale.dir
const externalUrl = resolvePortfolioExternalUrl(portfolio.projectUrl)
return (
<article className={cardStyles.card}>
@@ -129,6 +133,18 @@ export function PortfolioCard({
<Pencil size={16} />
</button>
</Tooltip>
{externalUrl ? (
<Tooltip label={externalUrl}>
<a
href={externalUrl}
target="_blank"
rel="noopener noreferrer"
aria-label={t('portfolio.card.openLink')}
>
<Link2 size={16} />
</a>
</Tooltip>
) : null}
<Tooltip label={t('portfolio.card.comments')}>
<button
type="button"
@@ -181,6 +181,19 @@
transition: background 0.2s, color 0.2s;
}
.controls a {
position: relative;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
color: var(--text-secondary);
text-decoration: none;
transition: background 0.2s, color 0.2s;
}
.iconBtn {
position: relative;
}
@@ -217,6 +230,11 @@
color: var(--primary);
}
.controls a:hover {
background: rgba(var(--primary-rgb) / 0.1);
color: var(--primary);
}
.controls button:disabled {
opacity: 0.35;
cursor: not-allowed;