- Add TOTP-based MFA with setup, verify, disable, backup codes, and challenge flow - Add PII field encryption middleware with AES-256-GCM and deterministic search hashes - Add agents, inquiries, and leads domain modules with entities, events, value objects - Add web dashboard pages for inquiries and leads with detail dialogs - Add 30+ component tests (valuation, charts, listings, search, providers, UI) - Add Prisma migrations for encryption hash columns and MFA TOTP support - Fix all ESLint errors (unused imports, duplicate imports, lint auto-fixes) - Update dependencies and lock file - Clean up obsolete exploration/QA docs, add audit documentation Co-Authored-By: Paperclip <noreply@paperclip.ing>
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import { Badge } from '@/components/ui/badge';
|
|
import type { InquiryReadDto } from '@/lib/inquiries-api';
|
|
|
|
interface InquiryStatusBadgeProps {
|
|
isRead: boolean;
|
|
}
|
|
|
|
export function InquiryStatusBadge({ isRead }: InquiryStatusBadgeProps) {
|
|
if (isRead) {
|
|
return <Badge variant="secondary">Đã đọc</Badge>;
|
|
}
|
|
return <Badge variant="info">Chưa đọc</Badge>;
|
|
}
|
|
|
|
interface InquiryRowProps {
|
|
inquiry: InquiryReadDto;
|
|
onSelect: (inquiry: InquiryReadDto) => void;
|
|
}
|
|
|
|
export function InquiryRow({ inquiry, onSelect }: InquiryRowProps) {
|
|
return (
|
|
<tr
|
|
className="border-b last:border-0 cursor-pointer transition-colors hover:bg-accent/50"
|
|
onClick={() => onSelect(inquiry)}
|
|
>
|
|
<td className="p-3">
|
|
<div className="flex flex-col gap-0.5">
|
|
<span className="font-medium">{inquiry.userName}</span>
|
|
<span className="text-xs text-muted-foreground">{inquiry.userPhone}</span>
|
|
</div>
|
|
</td>
|
|
<td className="p-3">
|
|
<span className="line-clamp-1 text-sm text-muted-foreground">
|
|
{inquiry.listingTitle}
|
|
</span>
|
|
</td>
|
|
<td className="hidden p-3 sm:table-cell">
|
|
<span className="line-clamp-2 text-sm">{inquiry.message}</span>
|
|
</td>
|
|
<td className="p-3 text-center">
|
|
<InquiryStatusBadge isRead={inquiry.isRead} />
|
|
</td>
|
|
<td className="p-3 text-right text-xs text-muted-foreground">
|
|
{new Date(inquiry.createdAt).toLocaleDateString('vi-VN', {
|
|
day: '2-digit',
|
|
month: '2-digit',
|
|
year: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
})}
|
|
</td>
|
|
</tr>
|
|
);
|
|
}
|