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:
co-authored by
Cursor
parent
85524544ca
commit
c289de5d2e
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user