- Added package.json to manage development scripts. - Updated restart-services.ps1 to call the new dev script for starting services. - Refactored start-admin.ps1, start-backend.ps1, start-frontend.ps1, and start-mcp.ps1 to utilize the dev script for starting respective services. - Enhanced stop-services.ps1 to improve process termination logic by matching command patterns.
73 lines
2.4 KiB
Plaintext
73 lines
2.4 KiB
Plaintext
---
|
|
import { getI18n } from '../lib/i18n';
|
|
import type { FriendLink } from '../lib/types';
|
|
|
|
interface Props {
|
|
friend: FriendLink;
|
|
}
|
|
|
|
const { friend } = Astro.props;
|
|
const { t } = getI18n(Astro);
|
|
---
|
|
|
|
<a
|
|
href={friend.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="terminal-panel terminal-interactive-card group flex h-full items-start gap-4 p-4"
|
|
>
|
|
<div class="shrink-0">
|
|
{friend.avatar ? (
|
|
<div class="relative w-12 h-12">
|
|
<img
|
|
src={friend.avatar}
|
|
alt={friend.name}
|
|
class="w-12 h-12 rounded-2xl object-cover border border-[var(--border-color)] bg-[var(--code-bg)]"
|
|
loading="lazy"
|
|
decoding="async"
|
|
onerror="this.style.display='none'; this.parentElement?.querySelector('[data-avatar-fallback]')?.classList.remove('hidden');"
|
|
/>
|
|
<div
|
|
data-avatar-fallback
|
|
class="hidden w-12 h-12 rounded-2xl bg-[var(--code-bg)] border border-[var(--border-color)] items-center justify-center text-sm font-bold text-[var(--primary)]"
|
|
>
|
|
{friend.name.charAt(0).toUpperCase()}
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div class="w-12 h-12 rounded-2xl bg-[var(--code-bg)] border border-[var(--border-color)] flex items-center justify-center text-sm font-bold text-[var(--primary)]">
|
|
{friend.name.charAt(0).toUpperCase()}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div class="flex-1 min-w-0">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<h4 class="font-bold text-[var(--title-color)] group-hover:text-[var(--primary)] transition-colors truncate text-base">
|
|
{friend.name}
|
|
</h4>
|
|
<i class="fas fa-external-link-alt text-xs text-[var(--text-tertiary)] opacity-0 group-hover:opacity-100 transition-opacity"></i>
|
|
</div>
|
|
|
|
{friend.description && (
|
|
<p class="text-sm text-[var(--text-secondary)] line-clamp-2 leading-6">{friend.description}</p>
|
|
)}
|
|
|
|
<div class="mt-3 flex items-center justify-between gap-3">
|
|
{friend.category ? (
|
|
<span class="terminal-chip text-xs py-1 px-2.5">
|
|
<i class="fas fa-folder text-[10px]"></i>
|
|
<span>{friend.category}</span>
|
|
</span>
|
|
) : (
|
|
<span class="text-xs text-[var(--text-tertiary)] font-mono">{t('friendCard.externalLink')}</span>
|
|
)}
|
|
|
|
<span class="terminal-link-arrow">
|
|
<span>{t('common.visit')}</span>
|
|
<i class="fas fa-arrow-up-right-from-square text-xs"></i>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</a>
|