92 lines
3.1 KiB
TypeScript
92 lines
3.1 KiB
TypeScript
import React from 'react'
|
|
import { motion } from 'framer-motion'
|
|
import { FaEnvelope, FaPhone, FaBriefcase, FaMapMarkerAlt } from 'react-icons/fa'
|
|
import { AVATAR_URL } from '@/constants/app.constant'
|
|
import { Avatar } from '@/components/ui'
|
|
|
|
interface UserProfileCardProps {
|
|
user: {
|
|
id: string
|
|
name: string
|
|
title: string
|
|
email?: string
|
|
phoneNumber?: string
|
|
department?: string
|
|
tenantId: string
|
|
}
|
|
position?: 'top' | 'bottom'
|
|
}
|
|
|
|
const UserProfileCard: React.FC<UserProfileCardProps> = ({ user, position = 'bottom' }) => {
|
|
return (
|
|
<motion.div
|
|
initial={{ opacity: 0, scale: 0.95, y: position === 'bottom' ? -10 : 10 }}
|
|
animate={{ opacity: 1, scale: 1, y: 0 }}
|
|
exit={{ opacity: 0, scale: 0.95, y: position === 'bottom' ? -10 : 10 }}
|
|
transition={{ duration: 0.15 }}
|
|
className={`absolute left-0 ${
|
|
position === 'bottom' ? 'top-full mt-2' : 'bottom-full mb-2'
|
|
} z-50 w-72 bg-white dark:bg-gray-800 rounded-lg shadow-xl border border-gray-200 dark:border-gray-700 p-4`}
|
|
>
|
|
{/* Header */}
|
|
<div className="flex items-start gap-3 mb-3 pb-3 border-b border-gray-200 dark:border-gray-700">
|
|
<Avatar size={48} shape="circle" src={AVATAR_URL(user.id, user.tenantId)} />
|
|
|
|
<div className="flex-1 min-w-0">
|
|
<h3 className="font-bold text-gray-900 dark:text-gray-100 text-lg mb-1">
|
|
{user.name}
|
|
</h3>
|
|
<p className="text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
<FaBriefcase className="w-4 h-4" />
|
|
{user.title}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Contact Info */}
|
|
<div className="space-y-2">
|
|
{user.email && (
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<FaEnvelope className="w-4 h-4 text-gray-400 flex-shrink-0" />
|
|
<a
|
|
href={`mailto:${user.email}`}
|
|
className="text-blue-600 dark:text-blue-400 hover:underline truncate"
|
|
>
|
|
{user.email}
|
|
</a>
|
|
</div>
|
|
)}
|
|
|
|
{user.phoneNumber && (
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<FaPhone className="w-4 h-4 text-gray-400 flex-shrink-0" />
|
|
<a
|
|
href={`tel:${user.phoneNumber}`}
|
|
className="text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400"
|
|
>
|
|
{user.phoneNumber}
|
|
</a>
|
|
</div>
|
|
)}
|
|
|
|
{user.department && (
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<FaBriefcase className="w-4 h-4 text-gray-400 flex-shrink-0" />
|
|
<span className="text-gray-700 dark:text-gray-300">{user.department}</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Arrow indicator */}
|
|
<div
|
|
className={`absolute left-6 ${
|
|
position === 'bottom' ? '-top-2' : '-bottom-2'
|
|
} w-4 h-4 bg-white dark:bg-gray-800 border-l border-t border-gray-200 dark:border-gray-700 transform ${
|
|
position === 'bottom' ? 'rotate-45' : '-rotate-135'
|
|
}`}
|
|
/>
|
|
</motion.div>
|
|
)
|
|
}
|
|
|
|
export default UserProfileCard
|