|
import React from 'react'; |
|
import { useDispatch, useSelector } from 'react-redux'; |
|
import { deleteLinkedInAccount, setPrimaryLinkedInAccount } from '../../store/reducers/linkedinAccountsSlice'; |
|
|
|
const LinkedInAccountCard = ({ account, onRefresh }) => { |
|
const dispatch = useDispatch(); |
|
const { deletingAccount, settingPrimary } = useSelector(state => state.linkedinAccounts); |
|
|
|
const handleDelete = async () => { |
|
if (window.confirm(`Are you sure you want to disconnect ${account.account_name}?`)) { |
|
try { |
|
await dispatch(deleteLinkedInAccount(account.id)).unwrap(); |
|
onRefresh(); |
|
} catch (error) { |
|
console.error('Failed to delete account:', error); |
|
} |
|
} |
|
}; |
|
|
|
const handleSetPrimary = async () => { |
|
try { |
|
await dispatch(setPrimaryLinkedInAccount(account.id)).unwrap(); |
|
onRefresh(); |
|
} catch (error) { |
|
console.error('Failed to set primary account:', error); |
|
} |
|
}; |
|
|
|
const isDeleting = deletingAccount === account.id; |
|
const isSettingPrimary = settingPrimary === account.id; |
|
|
|
return ( |
|
<div className="linkedin-account-card bg-white/90 backdrop-blur-sm rounded-xl p-6 border border-gray-200/50 shadow-sm hover:shadow-lg transition-all duration-300 transform hover:scale-[1.02] animate-slide-up"> |
|
<div className="account-header flex items-start space-x-4"> |
|
{account.picture ? ( |
|
<img |
|
src={account.picture} |
|
alt={`${account.given_name} ${account.family_name}`} |
|
className="w-16 h-16 rounded-full object-cover border-2 border-gray-200 shadow-sm" |
|
/> |
|
) : ( |
|
<div className="w-16 h-16 rounded-full bg-gradient-to-br from-blue-100 to-blue-200 flex items-center justify-center border-2 border-gray-200 shadow-sm"> |
|
<svg className="w-8 h-8 text-blue-600" fill="currentColor" viewBox="0 0 24 24"> |
|
<path d="M19 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14m-.5 15.5v-5.3a3.26 3.26 0 0 0-3.26-3.26c-.85 0-1.84.52-2.32 1.3v-1.11h-2.79v8.37h2.79v-4.93c0-.77.62-1.4 1.39-1.4a1.4 1.4 0 0 1 1.4 1.4v4.93h2.79M6.88 8.56a1.68 1.68 0 0 0 1.68-1.68c0-.93-.75-1.69-1.68-1.69a1.69 1.69 0 0 0-1.69 1.69c0 .93.76 1.68 1.69 1.68m1.39 9.94v-8.37H5.5v8.37h2.77z"/> |
|
</svg> |
|
</div> |
|
)} |
|
<div className="account-info flex-1 min-w-0"> |
|
<div className="flex items-center space-x-2 mb-1"> |
|
<h3 className="account-name text-lg font-semibold text-gray-900 truncate"> |
|
{account.given_name} {account.family_name} |
|
</h3> |
|
{account.is_primary && ( |
|
<span className="primary-badge inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gradient-to-r from-purple-500 to-purple-600 text-white shadow-sm"> |
|
<svg className="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" /> |
|
</svg> |
|
Primary |
|
</span> |
|
)} |
|
</div> |
|
<p className="account-handle text-sm text-gray-600 mb-3">@{account.sub}</p> |
|
|
|
{/* Account Status */} |
|
<div className="flex items-center space-x-4 text-xs text-gray-500"> |
|
<div className="flex items-center space-x-1"> |
|
<div className="w-2 h-2 bg-green-400 rounded-full"></div> |
|
<span>Connected</span> |
|
</div> |
|
<div className="flex items-center space-x-1"> |
|
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> |
|
</svg> |
|
<span>Active</span> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div className="account-actions flex flex-col sm:flex-row gap-3 mt-6 pt-6 border-t border-gray-200"> |
|
<button |
|
onClick={handleSetPrimary} |
|
disabled={account.is_primary || isSettingPrimary} |
|
className={`flex-1 font-medium py-2 px-4 rounded-lg transition-all duration-200 ${ |
|
account.is_primary |
|
? 'bg-gray-100 text-gray-500 cursor-not-allowed' |
|
: 'bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white shadow-sm hover:shadow-md disabled:from-blue-300 disabled:to-blue-400 disabled:cursor-not-allowed' |
|
}`} |
|
> |
|
{isSettingPrimary ? ( |
|
<> |
|
<svg className="animate-spin w-4 h-4 inline-block mr-2" fill="none" viewBox="0 0 24 24"> |
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle> |
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> |
|
</svg> |
|
Setting... |
|
</> |
|
) : account.is_primary ? ( |
|
<> |
|
<svg className="w-4 h-4 inline-block mr-2" fill="currentColor" viewBox="0 0 20 20"> |
|
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" /> |
|
</svg> |
|
Primary |
|
</> |
|
) : ( |
|
<> |
|
<svg className="w-4 h-4 inline-block mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /> |
|
</svg> |
|
Set Primary |
|
</> |
|
)} |
|
</button> |
|
|
|
<button |
|
onClick={handleDelete} |
|
disabled={isDeleting} |
|
className="flex-1 font-medium py-2 px-4 bg-gradient-to-r from-red-500 to-red-600 hover:from-red-600 hover:to-red-700 text-white rounded-lg transition-all duration-200 shadow-sm hover:shadow-md disabled:from-red-300 disabled:to-red-400 disabled:cursor-not-allowed" |
|
> |
|
{isDeleting ? ( |
|
<> |
|
<svg className="animate-spin w-4 h-4 inline-block mr-2" fill="none" viewBox="0 0 24 24"> |
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle> |
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> |
|
</svg> |
|
Disconnecting... |
|
</> |
|
) : ( |
|
<> |
|
<svg className="w-4 h-4 inline-block mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" /> |
|
</svg> |
|
Disconnect |
|
</> |
|
)} |
|
</button> |
|
</div> |
|
</div> |
|
); |
|
}; |
|
|
|
export default LinkedInAccountCard; |