Add column sorting and styles
This commit is contained in:
@@ -16,7 +16,7 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { TIME_RANGES } from "@/lib/constants";
|
import { TIME_RANGES } from "@/lib/constants";
|
||||||
import { Mail, MessageSquare } from "lucide-react";
|
import { Mail, MessageSquare, ArrowUpDown } from "lucide-react";
|
||||||
|
|
||||||
// Helper functions for formatting
|
// Helper functions for formatting
|
||||||
const formatRate = (value, isSMS = false, hideForSMS = false) => {
|
const formatRate = (value, isSMS = false, hideForSMS = false) => {
|
||||||
@@ -100,6 +100,13 @@ const KlaviyoCampaigns = ({ className }) => {
|
|||||||
direction: "desc",
|
direction: "desc",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleSort = (key) => {
|
||||||
|
setSortConfig((prev) => ({
|
||||||
|
key,
|
||||||
|
direction: prev.key === key && prev.direction === "desc" ? "asc" : "desc",
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
const fetchCampaigns = async () => {
|
const fetchCampaigns = async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
@@ -131,10 +138,23 @@ const KlaviyoCampaigns = ({ className }) => {
|
|||||||
// Sort campaigns
|
// Sort campaigns
|
||||||
const sortedCampaigns = [...campaigns].sort((a, b) => {
|
const sortedCampaigns = [...campaigns].sort((a, b) => {
|
||||||
const direction = sortConfig.direction === "desc" ? -1 : 1;
|
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
|
// Filter campaigns by search term and channels
|
||||||
@@ -204,22 +224,58 @@ const KlaviyoCampaigns = ({ className }) => {
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<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">
|
<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>
|
||||||
<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">
|
<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>
|
||||||
<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">
|
<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>
|
||||||
<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">
|
<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>
|
||||||
<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">
|
<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>
|
||||||
<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">
|
<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>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
Reference in New Issue
Block a user