fix inconsistency
This commit is contained in:
@@ -2,11 +2,33 @@
|
||||
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import { formatDistanceToNow } from "date-fns";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import {
|
||||
Plus,
|
||||
MessageCircle,
|
||||
Loader2,
|
||||
RefreshCw,
|
||||
ChevronLeft,
|
||||
ChevronRight
|
||||
} from "lucide-react";
|
||||
import axios from "axios";
|
||||
import { toast } from "sonner";
|
||||
import { getCookie } from "@/lib/client-utils";
|
||||
@@ -260,91 +282,127 @@ export default function ChatList() {
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className="w-full">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex justify-between items-center">
|
||||
<span>Customer Chats</span>
|
||||
<Button onClick={handleCreateChat}>New Chat</Button>
|
||||
</CardTitle>
|
||||
{vendorStores.length === 0 ? (
|
||||
<div className="text-sm text-muted-foreground">
|
||||
No store available. Please create a store first.
|
||||
</div>
|
||||
) : vendorStores.length === 1 ? (
|
||||
<div className="text-sm font-medium">
|
||||
{vendorStores[0].name}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center space-x-2">
|
||||
<label htmlFor="store-select" className="text-sm font-medium">
|
||||
Store:
|
||||
</label>
|
||||
<select
|
||||
id="store-select"
|
||||
value={selectedStore}
|
||||
onChange={handleStoreChange}
|
||||
className="rounded-md border border-input bg-background px-3 py-2 text-sm"
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Select
|
||||
value={selectedStore || "all"}
|
||||
onValueChange={(value) => setSelectedStore(value)}
|
||||
>
|
||||
<SelectTrigger className="w-48">
|
||||
<SelectValue placeholder="All Stores" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">All Stores</SelectItem>
|
||||
{vendorStores.map((store) => (
|
||||
<option key={store._id} value={store._id}>
|
||||
<SelectItem key={store._id} value={store._id}>
|
||||
{store.name}
|
||||
</option>
|
||||
</SelectItem>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{chats.length === 0 ? (
|
||||
<div className="text-center py-12 px-4">
|
||||
<div className="mb-4 mx-auto w-16 h-16 rounded-full bg-muted flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-muted-foreground">
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-lg font-medium">No chats available</h3>
|
||||
<p className="text-muted-foreground mt-2 mb-4">
|
||||
There are no customer conversations for this store yet.
|
||||
</p>
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={handleCreateChat}
|
||||
className="mt-2"
|
||||
>
|
||||
Start a new conversation
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{chats.map((chat) => (
|
||||
<div
|
||||
key={chat._id}
|
||||
className="flex items-center justify-between p-4 rounded-lg border cursor-pointer hover:bg-muted/50 transition-colors"
|
||||
onClick={() => handleChatClick(chat._id)}
|
||||
>
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar>
|
||||
<AvatarFallback>
|
||||
{chat.buyerId.slice(0, 2).toUpperCase()}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<h4 className="font-medium">Customer {chat.buyerId.slice(-4)}</h4>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{formatDistanceToNow(new Date(chat.lastUpdated), { addSuffix: true })}
|
||||
</p>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => fetchChats()}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? (
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<RefreshCw className="h-4 w-4" />
|
||||
)}
|
||||
<span className="ml-2">Refresh</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Button onClick={handleCreateChat} size="sm">
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
New Chat
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[200px]">Customer</TableHead>
|
||||
<TableHead>Last Activity</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead className="text-right">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{loading ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4} className="h-24 text-center">
|
||||
<Loader2 className="h-6 w-6 animate-spin mx-auto" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : chats.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4} className="h-24 text-center">
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<MessageCircle className="h-8 w-8 text-muted-foreground mb-2" />
|
||||
<p className="text-muted-foreground">No chats found</p>
|
||||
</div>
|
||||
</div>
|
||||
{unreadCounts.chatCounts[chat._id] > 0 && (
|
||||
<Badge variant="destructive">
|
||||
{unreadCounts.chatCounts[chat._id]} unread
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
chats.map((chat) => (
|
||||
<TableRow
|
||||
key={chat._id}
|
||||
className="cursor-pointer hover:bg-muted/50"
|
||||
onClick={() => handleChatClick(chat._id)}
|
||||
>
|
||||
<TableCell>
|
||||
<div className="flex items-center space-x-3">
|
||||
<Avatar>
|
||||
<AvatarFallback>
|
||||
{chat.buyerId?.slice(0, 2).toUpperCase() || 'CU'}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<div className="font-medium">Customer {chat.buyerId.slice(0, 4)}</div>
|
||||
{chat.orderId && (
|
||||
<div className="text-xs text-muted-foreground">
|
||||
Order #{chat.orderId}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{formatDistanceToNow(new Date(chat.lastUpdated), { addSuffix: true })}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{unreadCounts.chatCounts[chat._id] > 0 ? (
|
||||
<Badge variant="destructive" className="ml-1">
|
||||
{unreadCounts.chatCounts[chat._id]} new
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge variant="outline">Read</Badge>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleChatClick(chat._id);
|
||||
}}
|
||||
>
|
||||
View
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user