Add column sorting and styles
This commit is contained in:
@@ -16,7 +16,7 @@ import {
|
||||
} from "@/components/ui/select";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { TIME_RANGES } from "@/lib/constants";
|
||||
import { Mail, MessageSquare } from "lucide-react";
|
||||
import { Mail, MessageSquare, ArrowUpDown } from "lucide-react";
|
||||
|
||||
// Helper functions for formatting
|
||||
const formatRate = (value, isSMS = false, hideForSMS = false) => {
|
||||
@@ -100,6 +100,13 @@ const KlaviyoCampaigns = ({ className }) => {
|
||||
direction: "desc",
|
||||
});
|
||||
|
||||
const handleSort = (key) => {
|
||||
setSortConfig((prev) => ({
|
||||
key,
|
||||
direction: prev.key === key && prev.direction === "desc" ? "asc" : "desc",
|
||||
}));
|
||||
};
|
||||
|
||||
const fetchCampaigns = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
@@ -131,10 +138,23 @@ const KlaviyoCampaigns = ({ className }) => {
|
||||
// Sort campaigns
|
||||
const sortedCampaigns = [...campaigns].sort((a, b) => {
|
||||
const direction = sortConfig.direction === "desc" ? -1 : 1;
|
||||
if (sortConfig.key === "send_time") {
|
||||
return direction * (DateTime.fromISO(a.send_time) - DateTime.fromISO(b.send_time));
|
||||
|
||||
switch (sortConfig.key) {
|
||||
case "send_time":
|
||||
return direction * (DateTime.fromISO(a.send_time) - DateTime.fromISO(b.send_time));
|
||||
case "delivery_rate":
|
||||
return direction * ((a.stats.delivery_rate || 0) - (b.stats.delivery_rate || 0));
|
||||
case "open_rate":
|
||||
return direction * ((a.stats.open_rate || 0) - (b.stats.open_rate || 0));
|
||||
case "click_rate":
|
||||
return direction * ((a.stats.click_rate || 0) - (b.stats.click_rate || 0));
|
||||
case "click_to_open_rate":
|
||||
return direction * ((a.stats.click_to_open_rate || 0) - (b.stats.click_to_open_rate || 0));
|
||||
case "conversion_value":
|
||||
return direction * ((a.stats.conversion_value || 0) - (b.stats.conversion_value || 0));
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return direction * (a[sortConfig.key] - b[sortConfig.key]);
|
||||
});
|
||||
|
||||
// Filter campaigns by search term and channels
|
||||
@@ -204,22 +224,58 @@ const KlaviyoCampaigns = ({ className }) => {
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="p-2 text-left font-medium sticky top-0 bg-white dark:bg-gray-900 z-10 text-gray-900 dark:text-gray-100">
|
||||
Campaign
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => handleSort("send_time")}
|
||||
className="w-full justify-start h-8"
|
||||
>
|
||||
Campaign
|
||||
</Button>
|
||||
</th>
|
||||
<th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900 z-10 text-gray-900 dark:text-gray-100">
|
||||
Delivery
|
||||
<Button
|
||||
variant={sortConfig.key === "delivery_rate" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("delivery_rate")}
|
||||
className="w-full justify-center h-8"
|
||||
>
|
||||
Delivery
|
||||
</Button>
|
||||
</th>
|
||||
<th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900 z-10 text-gray-900 dark:text-gray-100">
|
||||
Opens
|
||||
<Button
|
||||
variant={sortConfig.key === "open_rate" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("open_rate")}
|
||||
className="w-full justify-center h-8"
|
||||
>
|
||||
Opens
|
||||
</Button>
|
||||
</th>
|
||||
<th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900 z-10 text-gray-900 dark:text-gray-100">
|
||||
Clicks
|
||||
<Button
|
||||
variant={sortConfig.key === "click_rate" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("click_rate")}
|
||||
className="w-full justify-center h-8"
|
||||
>
|
||||
Clicks
|
||||
</Button>
|
||||
</th>
|
||||
<th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900 z-10 text-gray-900 dark:text-gray-100">
|
||||
CTR
|
||||
<Button
|
||||
variant={sortConfig.key === "click_to_open_rate" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("click_to_open_rate")}
|
||||
className="w-full justify-center h-8"
|
||||
>
|
||||
CTR
|
||||
</Button>
|
||||
</th>
|
||||
<th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900 z-10 text-gray-900 dark:text-gray-100">
|
||||
Orders
|
||||
<Button
|
||||
variant={sortConfig.key === "conversion_value" ? "default" : "ghost"}
|
||||
onClick={() => handleSort("conversion_value")}
|
||||
className="w-full justify-center h-8"
|
||||
>
|
||||
Orders
|
||||
</Button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
Reference in New Issue
Block a user