67 lines
2.6 KiB
TypeScript
67 lines
2.6 KiB
TypeScript
import type { XPostData } from './types';
|
|
|
|
function formatNumber(n: number): string {
|
|
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
|
|
if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
|
|
return String(n);
|
|
}
|
|
|
|
export function XPostsCard({ data, onExpand }: { data: XPostData; onExpand: () => void }) {
|
|
const { query, posts } = data;
|
|
|
|
return (
|
|
<div className="bg-slate-50 border border-slate-200 rounded-xl p-4 my-2 not-prose" style={{ maxWidth: 600 }}>
|
|
{/* Header */}
|
|
<div className="flex items-center gap-2 mb-3">
|
|
<span className="font-bold text-slate-800" style={{ fontSize: 14 }}>𝕏</span>
|
|
<span className="font-semibold text-slate-700" style={{ fontSize: 13 }}>X 検索結果: 「{query}」</span>
|
|
<span className="text-slate-400 ml-auto" style={{ fontSize: 11 }}>{posts.length}件</span>
|
|
</div>
|
|
|
|
{/* Post list */}
|
|
<div className="space-y-1.5">
|
|
{posts.slice(0, 5).map((p) => (
|
|
<a
|
|
key={p.id}
|
|
href={p.postUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="flex items-start gap-2 bg-white border border-slate-200 rounded-lg px-3 py-2 no-underline hover:border-blue-300 hover:shadow-sm transition-all"
|
|
>
|
|
<img
|
|
src={p.authorImageUrl}
|
|
alt={p.authorScreenName}
|
|
className="rounded-full flex-shrink-0"
|
|
style={{ width: 24, height: 24 }}
|
|
loading="lazy"
|
|
/>
|
|
<div className="min-w-0 flex-1">
|
|
<div className="flex items-center gap-1">
|
|
<span className="font-semibold text-slate-800 truncate" style={{ fontSize: 12 }}>{p.authorName}</span>
|
|
<span className="text-slate-400 flex-shrink-0" style={{ fontSize: 11 }}>@{p.authorScreenName}</span>
|
|
</div>
|
|
<div className="text-slate-600 truncate" style={{ fontSize: 11 }}>{p.text.replace(/\n/g, ' ')}</div>
|
|
<div className="flex gap-3 mt-0.5 text-slate-400" style={{ fontSize: 10 }}>
|
|
<span>♥ {formatNumber(p.likes)}</span>
|
|
<span>🔁 {formatNumber(p.retweets)}</span>
|
|
<span>👁 {formatNumber(p.views)}</span>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
))}
|
|
</div>
|
|
|
|
{/* Expand button */}
|
|
<div className="text-center mt-2">
|
|
<button
|
|
onClick={onExpand}
|
|
className="text-blue-500 hover:text-blue-700 cursor-pointer bg-transparent border-none"
|
|
style={{ fontSize: 11 }}
|
|
>
|
|
▼ 詳細を表示
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|