102 lines
3 KiB
TypeScript
102 lines
3 KiB
TypeScript
|
|
import React from "react";
|
|
import { User } from "lucide-react";
|
|
import { Card } from "@/components/ui/card";
|
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import { supabase } from "@/lib/supabase";
|
|
import { formatDistanceToNow } from "date-fns";
|
|
|
|
interface Message {
|
|
id: string;
|
|
phone_number: string;
|
|
message: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export function ConversationList() {
|
|
const queryClient = useQueryClient();
|
|
|
|
const { data: messages, isLoading } = useQuery({
|
|
queryKey: ['messages'],
|
|
queryFn: async () => {
|
|
const { data, error } = await supabase
|
|
.from('messages')
|
|
.select('*')
|
|
.order('created_at', { ascending: false });
|
|
|
|
if (error) {
|
|
console.error('Error fetching messages:', error);
|
|
throw error;
|
|
}
|
|
|
|
return data as Message[];
|
|
},
|
|
refetchInterval: 5000 // Refetch every 5 seconds
|
|
});
|
|
|
|
// Subscribe to new messages
|
|
React.useEffect(() => {
|
|
const subscription = supabase
|
|
.channel('messages')
|
|
.on('postgres_changes', {
|
|
event: '*',
|
|
schema: 'public',
|
|
table: 'messages'
|
|
}, () => {
|
|
// Trigger a refetch when new messages arrive
|
|
queryClient.invalidateQueries({ queryKey: ['messages'] });
|
|
})
|
|
.subscribe();
|
|
|
|
return () => {
|
|
subscription.unsubscribe();
|
|
};
|
|
}, [queryClient]);
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="p-4">
|
|
<p className="text-muted-foreground">Loading conversations...</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const conversations = messages || [];
|
|
|
|
return (
|
|
<div className="space-y-4 p-4 animate-fadeIn">
|
|
<div className="flex items-center justify-between mb-6">
|
|
<h2 className="text-2xl font-semibold tracking-tight">Conversations</h2>
|
|
<span className="text-sm text-muted-foreground">
|
|
{conversations.length} active
|
|
</span>
|
|
</div>
|
|
<div className="grid gap-4">
|
|
{conversations.map((message) => (
|
|
<Card
|
|
key={message.id}
|
|
className="p-4 transition-all hover:shadow-md cursor-pointer group"
|
|
>
|
|
<div className="flex items-center space-x-4">
|
|
<div className="h-10 w-10 rounded-full bg-secondary flex items-center justify-center group-hover:bg-primary group-hover:text-white transition-colors">
|
|
<User className="h-5 w-5" />
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex justify-between items-start">
|
|
<h3 className="font-medium truncate">{message.phone_number}</h3>
|
|
<span className="text-xs text-muted-foreground whitespace-nowrap ml-2">
|
|
{formatDistanceToNow(new Date(message.created_at), { addSuffix: true })}
|
|
</span>
|
|
</div>
|
|
<p className="text-sm text-muted-foreground truncate">
|
|
{message.message}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|