Switch filter dropdown to toggles

This commit is contained in:
2024-12-27 12:28:44 -05:00
parent 7a224ee870
commit 5ea57b7286

View File

@@ -14,6 +14,7 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
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 } from "lucide-react";
@@ -48,7 +49,7 @@ const TableSkeleton = () => (
// Error alert component // Error alert component
const ErrorAlert = ({ description }) => ( const ErrorAlert = ({ description }) => (
<div className="p-4 mb-4 text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/10 rounded-lg"> <div className="p-4 m-6 text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/10 rounded-lg">
{description} {description}
</div> </div>
); );
@@ -87,18 +88,12 @@ const MetricCell = ({
); );
}; };
const CHANNEL_OPTIONS = [
{ value: "all", label: "All Campaigns" },
{ value: "email", label: "Email Only" },
{ value: "sms", label: "SMS Only" },
];
const KlaviyoCampaigns = ({ className }) => { const KlaviyoCampaigns = ({ className }) => {
const [campaigns, setCampaigns] = useState([]); const [campaigns, setCampaigns] = useState([]);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null); const [error, setError] = useState(null);
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState("");
const [selectedChannel, setSelectedChannel] = useState("all"); const [selectedChannels, setSelectedChannels] = useState({ email: true, sms: true });
const [selectedTimeRange, setSelectedTimeRange] = useState("last7days"); const [selectedTimeRange, setSelectedTimeRange] = useState("last7days");
const [sortConfig, setSortConfig] = useState({ const [sortConfig, setSortConfig] = useState({
key: "send_time", key: "send_time",
@@ -109,7 +104,7 @@ const KlaviyoCampaigns = ({ className }) => {
try { try {
setIsLoading(true); setIsLoading(true);
const response = await fetch( const response = await fetch(
`/api/klaviyo/reporting/campaigns/${selectedTimeRange}${selectedChannel !== 'all' ? `?channel=${selectedChannel}` : ''}` `/api/klaviyo/reporting/campaigns/${selectedTimeRange}`
); );
if (!response.ok) { if (!response.ok) {
@@ -131,7 +126,7 @@ const KlaviyoCampaigns = ({ className }) => {
fetchCampaigns(); fetchCampaigns();
const interval = setInterval(fetchCampaigns, 10 * 60 * 1000); // Refresh every 10 minutes const interval = setInterval(fetchCampaigns, 10 * 60 * 1000); // Refresh every 10 minutes
return () => clearInterval(interval); return () => clearInterval(interval);
}, [selectedTimeRange, selectedChannel]); }, [selectedTimeRange]); // Only refresh when time range changes
// Sort campaigns // Sort campaigns
const sortedCampaigns = [...campaigns].sort((a, b) => { const sortedCampaigns = [...campaigns].sort((a, b) => {
@@ -142,11 +137,11 @@ const KlaviyoCampaigns = ({ className }) => {
return direction * (a[sortConfig.key] - b[sortConfig.key]); return direction * (a[sortConfig.key] - b[sortConfig.key]);
}); });
// Filter campaigns by search term and channel // Filter campaigns by search term and channels
const filteredCampaigns = sortedCampaigns.filter( const filteredCampaigns = sortedCampaigns.filter(
(campaign) => (campaign) =>
campaign?.name?.toLowerCase().includes((searchTerm || "").toLowerCase()) && campaign?.name?.toLowerCase().includes((searchTerm || "").toLowerCase()) &&
(selectedChannel === "all" || campaign?.channel === selectedChannel) selectedChannels[campaign?.channel]
); );
if (isLoading) { if (isLoading) {
@@ -171,18 +166,24 @@ const KlaviyoCampaigns = ({ className }) => {
Campaigns Campaigns
</CardTitle> </CardTitle>
<div className="flex gap-2"> <div className="flex gap-2">
<Select value={selectedChannel} onValueChange={setSelectedChannel}> <div className="flex flex-wrap gap-1 items-center">
<SelectTrigger className="w-[180px]"> <Button
<SelectValue placeholder="Select channel" /> variant={selectedChannels.email ? "default" : "outline"}
</SelectTrigger> size="sm"
<SelectContent> onClick={() => setSelectedChannels(prev => ({ ...prev, email: !prev.email }))}
{CHANNEL_OPTIONS.map((option) => ( >
<SelectItem key={option.value} value={option.value}> <Mail className="h-4 w-4" />
{option.label} Email
</SelectItem> </Button>
))} <Button
</SelectContent> variant={selectedChannels.sms ? "default" : "outline"}
</Select> size="sm"
onClick={() => setSelectedChannels(prev => ({ ...prev, sms: !prev.sms }))}
>
<MessageSquare className="h-4 w-4" />
SMS
</Button>
</div>
<Select value={selectedTimeRange} onValueChange={setSelectedTimeRange}> <Select value={selectedTimeRange} onValueChange={setSelectedTimeRange}>
<SelectTrigger className="w-[180px]"> <SelectTrigger className="w-[180px]">
<SelectValue placeholder="Select time range" /> <SelectValue placeholder="Select time range" />
@@ -233,14 +234,14 @@ const KlaviyoCampaigns = ({ className }) => {
<TooltipTrigger asChild> <TooltipTrigger asChild>
<td className="p-2 align-top"> <td className="p-2 align-top">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="font-medium text-gray-900 dark:text-gray-100">
{campaign.name}
</div>
{campaign.channel === 'sms' ? ( {campaign.channel === 'sms' ? (
<MessageSquare className="h-4 w-4 text-gray-500" /> <MessageSquare className="h-4 w-4 text-gray-500" />
) : ( ) : (
<Mail className="h-4 w-4 text-gray-500" /> <Mail className="h-4 w-4 text-gray-500" />
)} )}
<div className="font-medium text-gray-900 dark:text-gray-100">
{campaign.name}
</div>
</div> </div>
<div className="text-sm text-gray-500 dark:text-gray-400 truncate max-w-[300px]"> <div className="text-sm text-gray-500 dark:text-gray-400 truncate max-w-[300px]">
{campaign.subject} {campaign.subject}