Switch filter dropdown to toggles
This commit is contained in:
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user