114 lines
5.3 KiB
TypeScript
114 lines
5.3 KiB
TypeScript
'use client';
|
|
|
|
import { User } from '@/types/user';
|
|
import { formatDate, formatPrice, getFullName, getEmail, getMobile } from '@/lib/utils';
|
|
import { CalendarIcon, EnvelopeIcon, PhoneIcon, WalletIcon, UserIcon } from '@heroicons/react/24/outline';
|
|
|
|
interface UserInfoProps {
|
|
user: User;
|
|
}
|
|
|
|
export default function UserInfo({ user }: UserInfoProps) {
|
|
const fullName = getFullName(user);
|
|
const initials = fullName
|
|
.split(' ')
|
|
.map((w) => w[0])
|
|
.slice(0, 2)
|
|
.join('')
|
|
.toUpperCase();
|
|
|
|
const stats = [
|
|
{
|
|
label: 'کیف پول',
|
|
value: `${formatPrice(user.wallet)} تومان`,
|
|
icon: WalletIcon,
|
|
color: 'bg-emerald-50 dark:bg-emerald-500/10 text-emerald-600 dark:text-emerald-400',
|
|
},
|
|
{
|
|
label: 'عضویت',
|
|
value: formatDate(user.created_at),
|
|
icon: CalendarIcon,
|
|
color: 'bg-blue-50 dark:bg-blue-500/10 text-blue-600 dark:text-blue-400',
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className="bg-white dark:bg-gray-900 rounded-2xl ring-1 ring-gray-200 dark:ring-gray-800 shadow-sm overflow-hidden mb-6">
|
|
{/* Profile Header */}
|
|
<div className="bg-gradient-to-l from-indigo-600 to-indigo-700 px-6 py-5">
|
|
<div className="flex items-center gap-4">
|
|
<div className="h-14 w-14 rounded-2xl bg-white/20 backdrop-blur-sm flex items-center justify-center text-white font-bold text-lg flex-shrink-0">
|
|
{initials || <UserIcon className="h-6 w-6" />}
|
|
</div>
|
|
<div className="min-w-0">
|
|
<h3 className="text-lg font-bold text-white truncate">
|
|
{fullName || 'کاربر بدون نام'}
|
|
</h3>
|
|
<div className="flex items-center gap-3 mt-1">
|
|
{user.email && (
|
|
<span className="text-sm text-indigo-100 flex items-center gap-1" dir="ltr">
|
|
<EnvelopeIcon className="h-3.5 w-3.5" />
|
|
{user.email}
|
|
</span>
|
|
)}
|
|
{user.mobile && (
|
|
<span className="text-sm text-indigo-100 flex items-center gap-1" dir="ltr">
|
|
<PhoneIcon className="h-3.5 w-3.5" />
|
|
{user.mobile}
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Stats Row */}
|
|
<div className="grid grid-cols-2 divide-x divide-gray-200 dark:divide-gray-800 border-b border-gray-200 dark:border-gray-800">
|
|
{stats.map((stat) => (
|
|
<div key={stat.label} className="px-5 py-4">
|
|
<div className="flex items-center gap-2 mb-1">
|
|
<div className={`h-7 w-7 rounded-lg flex items-center justify-center ${stat.color}`}>
|
|
<stat.icon className="h-3.5 w-3.5" />
|
|
</div>
|
|
<span className="text-xs text-gray-500 dark:text-gray-400">{stat.label}</span>
|
|
</div>
|
|
<p className="text-sm font-semibold text-gray-900 dark:text-gray-100" dir="ltr">{stat.value}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Details Grid */}
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-px bg-gray-200 dark:bg-gray-800">
|
|
<InfoRow icon={UserIcon} label="نام کامل" value={getFullName(user)} />
|
|
<InfoRow icon={EnvelopeIcon} label="ایمیل" value={getEmail(user.email)} dir="ltr" />
|
|
<InfoRow icon={PhoneIcon} label="شماره موبایل" value={getMobile(user.mobile)} dir="ltr" />
|
|
<InfoRow icon={WalletIcon} label="موجودی کیف پول" value={`${formatPrice(user.wallet)} تومان`} />
|
|
{user.birthday && (
|
|
<InfoRow icon={CalendarIcon} label="تاریخ تولد" value={formatDate(user.birthday)} />
|
|
)}
|
|
{user.gender && (
|
|
<InfoRow
|
|
icon={UserIcon}
|
|
label="جنسیت"
|
|
value={user.gender === 'male' ? 'مرد' : user.gender === 'female' ? 'زن' : user.gender}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function InfoRow({ icon: Icon, label, value, dir }: { icon: React.ElementType; label: string; value: string; dir?: string }) {
|
|
return (
|
|
<div className="bg-white dark:bg-gray-900 px-5 py-3.5 flex items-center gap-3">
|
|
<div className="h-7 w-7 rounded-lg bg-gray-100 dark:bg-gray-800 flex items-center justify-center flex-shrink-0">
|
|
<Icon className="h-3.5 w-3.5 text-gray-400 dark:text-gray-500" />
|
|
</div>
|
|
<div className="min-w-0">
|
|
<p className="text-xs text-gray-500 dark:text-gray-400">{label}</p>
|
|
<p className="text-sm font-medium text-gray-900 dark:text-gray-100 truncate" dir={dir}>{value}</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|