veza/apps/web/src/components/user/UserCard.tsx

89 lines
2.8 KiB
TypeScript
Raw Normal View History

import React from 'react';
import { Card } from '../ui/card';
import { Button } from '../ui/button';
import { CheckCircle, MoreHorizontal } from 'lucide-react';
import { User } from '../../types';
interface UserCardProps {
user: Partial<User>;
onFollow?: () => void;
onView?: () => void;
isFollowing?: boolean;
}
export const UserCard: React.FC<UserCardProps> = ({
user,
onFollow,
onView,
isFollowing,
}) => {
return (
<Card
variant="default"
className="flex flex-col items-center text-center p-6 group hover:border-kodo-cyan/30 transition-all relative overflow-hidden"
>
{/* Banner/Background Accent */}
<div className="absolute top-0 left-0 right-0 h-16 bg-gradient-to-b from-white/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity"></div>
2026-01-07 18:39:21 +00:00
<div className="relative mb-4 cursor-pointer" onClick={onView}>
<div className="w-20 h-20 rounded-full border-2 border-kodo-steel p-1 bg-kodo-ink group-hover:border-kodo-cyan transition-colors">
<img
src={user.avatar}
alt={user.username}
className="w-full h-full rounded-full object-cover"
/>
</div>
{user.roles?.includes('VERIFIED') && (
<div className="absolute bottom-0 right-0 bg-kodo-cyan text-black rounded-full p-0.5 border-2 border-kodo-ink">
<CheckCircle className="w-3 h-3" />
</div>
)}
</div>
<h3
className="font-bold text-white text-lg mb-1 cursor-pointer hover:underline"
onClick={onView}
>
{user.username}
</h3>
<p className="text-xs text-gray-400 font-mono mb-3">@{user.username}</p>
{user.bio && (
<p className="text-sm text-gray-400 mb-4 line-clamp-2 min-h-[2.5em]">
{user.bio}
</p>
)}
2026-01-07 18:39:21 +00:00
<div className="flex justify-center gap-4 w-full mb-4 border-t border-b border-white/5 py-2">
<div>
<div className="font-bold text-white">{user.stats?.tracks || 0}</div>
<div className="text-[10px] text-gray-500 uppercase">Tracks</div>
</div>
<div>
<div className="font-bold text-white">
{user.stats?.followers || 0}
</div>
<div className="text-[10px] text-gray-500 uppercase">Fans</div>
</div>
</div>
<div className="flex gap-2 w-full">
<Button
variant={isFollowing ? 'ghost' : 'primary'}
size="sm"
className={`flex-1 ${isFollowing ? 'border border-kodo-steel text-gray-400' : ''}`}
onClick={onFollow}
>
{isFollowing ? 'Following' : 'Follow'}
</Button>
<Button
variant="ghost"
size="sm"
className="border border-kodo-steel"
icon={<MoreHorizontal className="w-4 h-4" />}
/>
</div>
</Card>
);
};