tahamajs/IE / Projects /front /src /components /admin /AdminConversationsList.tsx
tahamajs's picture
download
raw
3.42 kB
// src/components/admin/AdminConversationsList.tsx
import { useState } from "react";
import { Trash2, MessageSquare, Clock, RefreshCw } from "lucide-react";
import { toast } from "react-toastify";
interface AdminConversation {
id: number;
user1: string;
user2: string;
lastActivity?: string;
messageCount?: number;
}
interface AdminConversationsListProps {
conversations: AdminConversation[];
onDelete: (id: number) => Promise<void>;
}
export function AdminConversationsList({ conversations, onDelete }: AdminConversationsListProps) {
const [loadingStates, setLoadingStates] = useState<Record<number, boolean>>({});
const handleDelete = async (id: number) => {
setLoadingStates((prev) => ({ ...prev, [id]: true }));
try {
await onDelete(id);
toast.success("Conversation deleted successfully");
} catch (err) {
console.error(err);
} finally {
setLoadingStates((prev) => ({ ...prev, [id]: false }));
}
};
if (!conversations || conversations.length === 0) {
return (
<div className="text-center py-12 bg-white/40 dark:bg-gray-900/40 backdrop-blur-md border border-gray-200 dark:border-gray-800 rounded-2xl text-gray-500">
No private conversations found.
</div>
);
}
return (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{conversations.map((c) => {
const isLoading = loadingStates[c.id] || false;
return (
<div
key={c.id}
className="bg-white/40 dark:bg-gray-900/40 backdrop-blur-md border border-gray-200/50 dark:border-gray-800/50 rounded-2xl p-5 shadow-lg flex justify-between items-center gap-4 transition duration-200 hover:shadow-xl hover:border-gray-300 dark:hover:border-gray-700"
>
<div className="flex items-center gap-3.5 min-w-0">
<div className="w-11 h-11 rounded-xl bg-indigo-500/10 dark:bg-indigo-500/20 text-indigo-600 dark:text-indigo-400 flex items-center justify-center shrink-0">
<MessageSquare className="w-5 h-5" />
</div>
<div className="min-w-0">
<h3 className="font-semibold text-sm truncate text-gray-850 dark:text-gray-150">
{c.user1} ↔ {c.user2}
</h3>
<div className="flex items-center gap-2 mt-1 text-[10px] font-medium text-gray-400">
<span>{c.messageCount ?? 0} messages</span>
<span>•</span>
<span className="flex items-center gap-0.5">
<Clock className="w-3 h-3" />
Last activity: {c.lastActivity ? new Date(c.lastActivity).toLocaleDateString() : "unknown"}
</span>
</div>
</div>
</div>
<div className="shrink-0">
{isLoading ? (
<RefreshCw className="w-4 h-4 text-gray-400 animate-spin" />
) : (
<button
onClick={() => handleDelete(c.id)}
className="p-2 text-gray-400 hover:text-rose-500 hover:bg-rose-50 dark:hover:bg-rose-500/10 rounded-xl transition duration-200"
title="Delete Conversation"
>
<Trash2 className="w-4.5 h-4.5" />
</button>
)}
</div>
</div>
);
})}
</div>
);
}

Xet Storage Details

Size:
3.42 kB
·
Xet hash:
74a2a2283f82699472ea844d78d09b714218eba3ec6e1081adf8d3eb609ebf56

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.