fix auth
This commit is contained in:
@@ -20,7 +20,9 @@ import {
|
|||||||
Loader2,
|
Loader2,
|
||||||
RefreshCw,
|
RefreshCw,
|
||||||
Eye,
|
Eye,
|
||||||
User
|
User,
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { clientFetch } from "@/lib/client-utils";
|
import { clientFetch } from "@/lib/client-utils";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
@@ -41,12 +43,23 @@ interface UnreadCounts {
|
|||||||
chatCounts: Record<string, number>;
|
chatCounts: Record<string, number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ChatResponse {
|
||||||
|
chats: Chat[];
|
||||||
|
page: number;
|
||||||
|
totalPages: number;
|
||||||
|
totalChats: number;
|
||||||
|
}
|
||||||
|
|
||||||
export default function ChatTable() {
|
export default function ChatTable() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [chats, setChats] = useState<Chat[]>([]);
|
const [chats, setChats] = useState<Chat[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [unreadCounts, setUnreadCounts] = useState<UnreadCounts>({ totalUnread: 0, chatCounts: {} });
|
const [unreadCounts, setUnreadCounts] = useState<UnreadCounts>({ totalUnread: 0, chatCounts: {} });
|
||||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [totalPages, setTotalPages] = useState(1);
|
||||||
|
const [totalChats, setTotalChats] = useState(0);
|
||||||
|
const ITEMS_PER_PAGE = 10;
|
||||||
|
|
||||||
// Initialize audio element for notifications
|
// Initialize audio element for notifications
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -90,7 +103,7 @@ export default function ChatTable() {
|
|||||||
return { vendorId, authToken };
|
return { vendorId, authToken };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fetch chats when component mounts
|
// Fetch chats when component mounts or page changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchChats();
|
fetchChats();
|
||||||
|
|
||||||
@@ -100,7 +113,7 @@ export default function ChatTable() {
|
|||||||
}, 30000); // Check every 30 seconds
|
}, 30000); // Check every 30 seconds
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, []);
|
}, [currentPage]);
|
||||||
|
|
||||||
// Fetch unread counts
|
// Fetch unread counts
|
||||||
const fetchUnreadCounts = async () => {
|
const fetchUnreadCounts = async () => {
|
||||||
@@ -124,7 +137,7 @@ export default function ChatTable() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fetch chats
|
// Fetch chats with pagination
|
||||||
const fetchChats = async () => {
|
const fetchChats = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
@@ -132,10 +145,23 @@ export default function ChatTable() {
|
|||||||
// Get the vendor ID from the auth token
|
// Get the vendor ID from the auth token
|
||||||
const { vendorId } = getVendorIdFromToken();
|
const { vendorId } = getVendorIdFromToken();
|
||||||
|
|
||||||
// Now fetch chats for this vendor using clientFetch
|
// Now fetch chats for this vendor using clientFetch with pagination
|
||||||
const response = await clientFetch(`/chats/vendor/${vendorId}`);
|
const response = await clientFetch(`/chats/vendor/${vendorId}?page=${currentPage}&limit=${ITEMS_PER_PAGE}`);
|
||||||
|
|
||||||
|
// Check if the response is the old format (array) or new paginated format
|
||||||
|
if (Array.isArray(response)) {
|
||||||
|
// Handle old API response format (backward compatibility)
|
||||||
|
setChats(response);
|
||||||
|
setTotalPages(1);
|
||||||
|
setTotalChats(response.length);
|
||||||
|
} else {
|
||||||
|
// Handle new paginated response format
|
||||||
|
setChats(response.chats || []);
|
||||||
|
setTotalPages(response.totalPages || 1);
|
||||||
|
setCurrentPage(response.page || 1);
|
||||||
|
setTotalChats(response.totalChats || 0);
|
||||||
|
}
|
||||||
|
|
||||||
setChats(Array.isArray(response) ? response : []);
|
|
||||||
await fetchUnreadCounts();
|
await fetchUnreadCounts();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch chats:", error);
|
console.error("Failed to fetch chats:", error);
|
||||||
@@ -156,13 +182,29 @@ export default function ChatTable() {
|
|||||||
router.push("/dashboard/chats/new");
|
router.push("/dashboard/chats/new");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle pagination
|
||||||
|
const goToNextPage = () => {
|
||||||
|
if (currentPage < totalPages) {
|
||||||
|
setCurrentPage(prev => prev + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const goToPrevPage = () => {
|
||||||
|
if (currentPage > 1) {
|
||||||
|
setCurrentPage(prev => prev - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={fetchChats}
|
onClick={() => {
|
||||||
|
setCurrentPage(1);
|
||||||
|
fetchChats();
|
||||||
|
}}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
>
|
>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@@ -266,6 +308,36 @@ export default function ChatTable() {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Pagination controls */}
|
||||||
|
{!loading && chats.length > 0 && (
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
Showing {chats.length} of {totalChats} chats
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={goToPrevPage}
|
||||||
|
disabled={currentPage <= 1 || loading}
|
||||||
|
>
|
||||||
|
<ChevronLeft className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
<div className="text-sm">
|
||||||
|
Page {currentPage} of {totalPages}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={goToNextPage}
|
||||||
|
disabled={currentPage >= totalPages || loading}
|
||||||
|
>
|
||||||
|
<ChevronRight className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -6,17 +6,10 @@
|
|||||||
* Get the authentication token from cookies or localStorage
|
* Get the authentication token from cookies or localStorage
|
||||||
*/
|
*/
|
||||||
export function getAuthToken(): string | null {
|
export function getAuthToken(): string | null {
|
||||||
const token = document.cookie
|
return document.cookie
|
||||||
.split('; ')
|
.split('; ')
|
||||||
.find(row => row.startsWith('Authorization='))
|
.find(row => row.startsWith('Authorization='))
|
||||||
?.split('=')[1] || localStorage.getItem('Authorization');
|
?.split('=')[1] || localStorage.getItem('Authorization');
|
||||||
|
|
||||||
// If token exists but doesn't have Bearer prefix, add it
|
|
||||||
if (token && !token.startsWith('Bearer ')) {
|
|
||||||
return `Bearer ${token}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,7 +30,7 @@ export async function logoutUser(): Promise<void> {
|
|||||||
await fetch(`/api/auth/logout`, {
|
await fetch(`/api/auth/logout`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': token,
|
'Authorization': `Bearer ${token}`,
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
|||||||
Reference in New Issue
Block a user