Update page.tsx

This commit is contained in:
NotII
2025-04-02 18:19:27 +01:00
parent 81a813c3f0
commit 5e810a8716

View File

@@ -38,10 +38,13 @@ import {
ArrowUpDown, ArrowUpDown,
MessageCircle, MessageCircle,
UserPlus, UserPlus,
MoreHorizontal MoreHorizontal,
Search,
X
} from "lucide-react"; } from "lucide-react";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuTrigger, DropdownMenuTrigger,
@@ -52,6 +55,8 @@ import {
export default function CustomerManagementPage() { export default function CustomerManagementPage() {
const router = useRouter(); const router = useRouter();
const [customers, setCustomers] = useState<CustomerStats[]>([]); const [customers, setCustomers] = useState<CustomerStats[]>([]);
const [filteredCustomers, setFilteredCustomers] = useState<CustomerStats[]>([]);
const [searchQuery, setSearchQuery] = useState("");
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const [totalPages, setTotalPages] = useState(1); const [totalPages, setTotalPages] = useState(1);
@@ -93,6 +98,7 @@ export default function CustomerManagementPage() {
}); });
setCustomers(sortedCustomers); setCustomers(sortedCustomers);
setFilteredCustomers(sortedCustomers);
setTotalPages(Math.ceil(response.total / itemsPerPage)); setTotalPages(Math.ceil(response.total / itemsPerPage));
} catch (err) { } catch (err) {
toast.error("Failed to fetch customers"); toast.error("Failed to fetch customers");
@@ -117,6 +123,21 @@ export default function CustomerManagementPage() {
} }
}, [router]); }, [router]);
// Add filter function to filter customers when search query changes
useEffect(() => {
if (!searchQuery.trim()) {
setFilteredCustomers(customers);
} else {
const query = searchQuery.toLowerCase().trim();
const filtered = customers.filter(customer => {
const usernameMatch = customer.telegramUsername?.toLowerCase().includes(query);
const userIdMatch = customer.telegramUserId.toString().includes(query);
return usernameMatch || userIdMatch;
});
setFilteredCustomers(filtered);
}
}, [searchQuery, customers]);
const handlePageChange = (newPage: number) => { const handlePageChange = (newPage: number) => {
setPage(newPage); setPage(newPage);
}; };
@@ -133,6 +154,10 @@ export default function CustomerManagementPage() {
})); }));
}; };
const clearSearch = () => {
setSearchQuery("");
};
// Format date with time // Format date with time
const formatDate = (dateString: string | null | undefined) => { const formatDate = (dateString: string | null | undefined) => {
if (!dateString) return "N/A"; if (!dateString) return "N/A";
@@ -161,7 +186,7 @@ export default function CustomerManagementPage() {
</div> </div>
<div className="bg-black/40 border border-zinc-800 rounded-md overflow-hidden"> <div className="bg-black/40 border border-zinc-800 rounded-md overflow-hidden">
<div className="p-4 border-b border-zinc-800 bg-black/60 flex justify-between items-center"> <div className="p-4 border-b border-zinc-800 bg-black/60 flex flex-col md:flex-row md:justify-between md:items-center gap-4">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="text-sm font-medium text-gray-400">Show:</div> <div className="text-sm font-medium text-gray-400">Show:</div>
@@ -178,10 +203,33 @@ export default function CustomerManagementPage() {
</div> </div>
</div> </div>
<div className="text-sm text-gray-400"> <div className="relative flex-1 max-w-md">
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<Search className="h-4 w-4 text-gray-400" />
</div>
<Input
type="text"
placeholder="Search by username or Telegram ID..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-10 pr-10 py-2 w-full bg-black/40 border-zinc-700 text-white"
/>
{searchQuery && (
<button
className="absolute inset-y-0 right-0 flex items-center pr-3"
onClick={clearSearch}
>
<X className="h-4 w-4 text-gray-400 hover:text-gray-200" />
</button>
)}
</div>
<div className="text-sm text-gray-400 whitespace-nowrap">
{loading {loading
? "Loading..." ? "Loading..."
: `Showing ${customers.length} of ${totalPages * itemsPerPage} customers`} : searchQuery
? `Found ${filteredCustomers.length} matching customers`
: `Showing ${filteredCustomers.length} of ${totalPages * itemsPerPage} customers`}
</div> </div>
</div> </div>
@@ -189,13 +237,22 @@ export default function CustomerManagementPage() {
<div className="p-8 flex justify-center bg-black/60"> <div className="p-8 flex justify-center bg-black/60">
<Loader2 className="h-8 w-8 animate-spin text-primary" /> <Loader2 className="h-8 w-8 animate-spin text-primary" />
</div> </div>
) : customers.length === 0 ? ( ) : filteredCustomers.length === 0 ? (
<div className="p-8 text-center bg-black/60"> <div className="p-8 text-center bg-black/60">
<Users className="h-12 w-12 mx-auto text-gray-500 mb-4" /> <Users className="h-12 w-12 mx-auto text-gray-500 mb-4" />
<h3 className="text-lg font-medium mb-2 text-white">No customers found</h3> <h3 className="text-lg font-medium mb-2 text-white">
{searchQuery ? "No customers matching your search" : "No customers found"}
</h3>
<p className="text-gray-500"> <p className="text-gray-500">
Once you have customers placing orders, they will appear here. {searchQuery
? "Try a different search term or clear the search"
: "Once you have customers placing orders, they will appear here."}
</p> </p>
{searchQuery && (
<Button variant="outline" size="sm" onClick={clearSearch} className="mt-4">
Clear search
</Button>
)}
</div> </div>
) : ( ) : (
<div className="overflow-x-auto"> <div className="overflow-x-auto">
@@ -234,7 +291,7 @@ export default function CustomerManagementPage() {
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{customers.map((customer) => ( {filteredCustomers.map((customer) => (
<TableRow <TableRow
key={customer.userId} key={customer.userId}
className={`cursor-pointer ${!customer.hasOrders ? "bg-black/30" : ""}`} className={`cursor-pointer ${!customer.hasOrders ? "bg-black/30" : ""}`}