2026-08-15 17:47:59 -04:00
|
|
|
import Link from 'next/link';
|
|
|
|
|
import { VOCAB } from '../lib/collection-vocabulary.js';
|
|
|
|
|
|
2026-06-04 12:21:58 -04:00
|
|
|
/**
|
2026-08-15 17:47:59 -04:00
|
|
|
* Recent adds to My Collection on /dashboard.
|
2026-06-04 12:21:58 -04:00
|
|
|
*/
|
2026-08-15 17:47:59 -04:00
|
|
|
export default function DashboardRecentActivity({ activities = [], loading = false }) {
|
2026-06-04 12:21:58 -04:00
|
|
|
return (
|
|
|
|
|
<section className="glass-panel rounded-2xl p-5 sm:p-6">
|
|
|
|
|
<header className="flex items-center justify-between mb-4">
|
|
|
|
|
<h2
|
|
|
|
|
className="text-lg font-bold flex items-center gap-2"
|
|
|
|
|
style={{ color: 'var(--text-primary)' }}
|
|
|
|
|
>
|
|
|
|
|
<span
|
|
|
|
|
className="inline-flex h-5 w-5 items-center justify-center rounded-md"
|
|
|
|
|
style={{
|
|
|
|
|
background:
|
|
|
|
|
'linear-gradient(135deg, rgb(255, 140, 30) 0%, rgb(216, 67, 21) 100%)',
|
|
|
|
|
}}
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
>
|
|
|
|
|
<svg
|
|
|
|
|
className="h-3.5 w-3.5"
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
fill="rgb(255, 255, 255)"
|
|
|
|
|
>
|
|
|
|
|
<path d="M13 10V3L4 14h7v7l9-11h-7z" />
|
|
|
|
|
</svg>
|
|
|
|
|
</span>
|
2026-08-15 17:47:59 -04:00
|
|
|
Recent activity
|
2026-06-04 12:21:58 -04:00
|
|
|
</h2>
|
2026-08-15 17:47:59 -04:00
|
|
|
<Link
|
|
|
|
|
href="/my-cards"
|
2026-06-04 12:21:58 -04:00
|
|
|
className="text-sm font-medium hover:underline focus:outline-none focus:ring-2 rounded-md px-1"
|
|
|
|
|
style={{
|
|
|
|
|
color: 'var(--accent-ember)',
|
|
|
|
|
'--tw-ring-color': 'var(--accent-ember)',
|
|
|
|
|
}}
|
|
|
|
|
>
|
2026-08-15 17:47:59 -04:00
|
|
|
View {VOCAB.MY_COLLECTION}
|
|
|
|
|
</Link>
|
2026-06-04 12:21:58 -04:00
|
|
|
</header>
|
|
|
|
|
|
2026-08-15 17:47:59 -04:00
|
|
|
{loading ? (
|
|
|
|
|
<ul className="space-y-3" aria-busy="true">
|
|
|
|
|
{[0, 1, 2].map((idx) => (
|
|
|
|
|
<li
|
|
|
|
|
key={idx}
|
|
|
|
|
className="h-12 rounded-xl motion-essential animate-pulse"
|
|
|
|
|
style={{ backgroundColor: 'var(--bg-tertiary)' }}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</ul>
|
|
|
|
|
) : activities.length === 0 ? (
|
|
|
|
|
<p className="text-sm" style={{ color: 'var(--text-secondary)' }}>
|
|
|
|
|
No recent adds yet. Scan a card or browse the catalog to start
|
|
|
|
|
building {VOCAB.MY_COLLECTION}.
|
2026-06-04 12:21:58 -04:00
|
|
|
</p>
|
2026-08-15 17:47:59 -04:00
|
|
|
) : (
|
|
|
|
|
<ul className="space-y-3">
|
|
|
|
|
{activities.map((row) => (
|
|
|
|
|
<li key={row.id} className="flex items-start gap-3">
|
2026-06-04 12:21:58 -04:00
|
|
|
<div
|
2026-08-15 17:47:59 -04:00
|
|
|
className="w-9 h-9 rounded-full flex items-center justify-center text-sm font-bold flex-shrink-0"
|
|
|
|
|
style={{
|
|
|
|
|
background:
|
|
|
|
|
'linear-gradient(135deg, rgb(255, 140, 30) 0%, rgb(216, 67, 21) 100%)',
|
|
|
|
|
color: 'rgb(255, 255, 255)',
|
|
|
|
|
boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.18)',
|
|
|
|
|
}}
|
|
|
|
|
aria-hidden="true"
|
2026-06-04 12:21:58 -04:00
|
|
|
>
|
2026-08-15 17:47:59 -04:00
|
|
|
{row.actor.initial}
|
2026-06-04 12:21:58 -04:00
|
|
|
</div>
|
2026-08-15 17:47:59 -04:00
|
|
|
<div className="flex-1 min-w-0">
|
|
|
|
|
<div className="text-sm" style={{ color: 'var(--text-primary)' }}>
|
|
|
|
|
<span className="font-semibold">{row.actor.name}</span>{' '}
|
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}>
|
|
|
|
|
{row.action}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
className="text-xs truncate"
|
|
|
|
|
style={{ color: 'var(--text-secondary)' }}
|
|
|
|
|
>
|
|
|
|
|
{row.subject}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<span
|
|
|
|
|
className="text-xs whitespace-nowrap flex-shrink-0"
|
2026-06-04 12:21:58 -04:00
|
|
|
style={{ color: 'var(--text-secondary)' }}
|
|
|
|
|
>
|
2026-08-15 17:47:59 -04:00
|
|
|
{row.time}
|
|
|
|
|
</span>
|
|
|
|
|
</li>
|
|
|
|
|
))}
|
|
|
|
|
</ul>
|
|
|
|
|
)}
|
2026-06-04 12:21:58 -04:00
|
|
|
</section>
|
|
|
|
|
);
|
|
|
|
|
}
|