ge-tool/components/UserResultItem.tsx

57 lines
2.1 KiB
TypeScript
Raw Permalink Normal View History

2025-12-10 06:41:43 +00:00
import React, { memo } from 'react';
import type { ResultDetail } from '../types';
import CheckIcon from './CheckIcon';
import XCircleIcon from './XCircleIcon';
interface UserResultItemProps {
detail: ResultDetail;
onErrorClick: (details: string) => void;
}
const UserResultItem: React.FC<UserResultItemProps> = ({ detail, onErrorClick }) => {
const isSuccess = detail.status === 'success';
const hasErrorDetails = !isSuccess && detail.errorDetails;
// Check if message contains "Đã có quyền" - should be yellow/warning
const isAlreadyHasPermission = isSuccess && detail.message?.includes('Đã có quyền');
// Determine status color: error=red, already has=yellow, success=green
const statusColor = !isSuccess
? 'text-rose-400'
: isAlreadyHasPermission
? 'text-amber-400'
: 'text-green-400';
const Icon = isSuccess ? CheckIcon : XCircleIcon;
const renderStatus = (className?: string) => {
const commonClasses = `flex items-center gap-2 ${statusColor}`;
if (hasErrorDetails) {
return (
<button
onClick={() => onErrorClick(detail.errorDetails!)}
className={`${commonClasses} hover:underline ${className || ''}`}
>
<Icon className="w-4 h-4 flex-shrink-0" />
<span className="text-xs">{detail.message}</span>
</button>
)
}
return (
<div className={`${commonClasses} ${className || ''}`}>
<Icon className="w-4 h-4 flex-shrink-0" />
<span className="text-xs">{detail.message}</span>
</div>
);
}
return (
<div className="grid grid-cols-1 sm:grid-cols-10 gap-x-4 gap-y-1 items-center p-2 rounded-md hover:bg-slate-700/30 font-mono text-sm">
<div className="truncate text-slate-300 sm:col-span-4" title={detail.username}>
{detail.username}
</div>
{renderStatus('sm:col-span-6')}
</div>
);
};
export default memo(UserResultItem);