File size: 7,282 Bytes
25f22bf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
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; |