feat(dashboard): add status filter for contacts

This commit is contained in:
Himanshu Ahuja
2025-06-03 18:48:27 -04:00
parent f877153e58
commit 45697cf6b1
@@ -9,7 +9,7 @@ import React, { useState } from "react";
import { type FieldError, useFieldArray, useForm } from "react-hook-form"; import { type FieldError, useFieldArray, useForm } from "react-hook-form";
import { toast } from "sonner"; import { toast } from "sonner";
import { z } from "zod"; import { z } from "zod";
import { Card, Empty, FullscreenLoader, Modal, Skeleton, Table, Toggle } from "../../components"; import { Card, Empty, FullscreenLoader, Modal, Skeleton, Table, Toggle, Dropdown } from "../../components";
import { Dashboard } from "../../layouts"; import { Dashboard } from "../../layouts";
import { searchContacts, useContacts } from "../../lib/hooks/contacts"; import { searchContacts, useContacts } from "../../lib/hooks/contacts";
import { useActiveProject } from "../../lib/hooks/projects"; import { useActiveProject } from "../../lib/hooks/projects";
@@ -33,6 +33,7 @@ interface ContactValues {
export default function Index() { export default function Index() {
const [page, setPage] = useState(1); const [page, setPage] = useState(1);
const [query, setQuery] = useState<string>(); const [query, setQuery] = useState<string>();
const [statusFilter, setStatusFilter] = useState<string>("all");
const project = useActiveProject(); const project = useActiveProject();
const { data: user } = useUser(); const { data: user } = useUser();
@@ -126,11 +127,20 @@ export default function Index() {
} }
if (search && query !== undefined) { if (search && query !== undefined) {
if (search.contacts.length > 0) { const filtered = search.contacts
.filter((c) =>
statusFilter === "all"
? true
: statusFilter === "subscribed"
? c.subscribed
: !c.subscribed,
);
if (filtered.length > 0) {
return ( return (
<> <>
<Table <Table
values={search.contacts values={filtered
.sort((a, b) => { .sort((a, b) => {
const aTrigger = a.triggers.length > 0 ? a.triggers.sort()[0].createdAt : a.createdAt; const aTrigger = a.triggers.length > 0 ? a.triggers.sort()[0].createdAt : a.createdAt;
@@ -184,11 +194,19 @@ export default function Index() {
} }
if (contacts) { if (contacts) {
if (contacts.contacts.length > 0) { const filtered = contacts.contacts.filter((c) =>
statusFilter === "all"
? true
: statusFilter === "subscribed"
? c.subscribed
: !c.subscribed,
);
if (filtered.length > 0) {
return ( return (
<> <>
<Table <Table
values={contacts.contacts values={filtered
.sort((a, b) => { .sort((a, b) => {
const aTrigger = a.triggers.length > 0 ? a.triggers.sort()[0].createdAt : a.createdAt; const aTrigger = a.triggers.length > 0 ? a.triggers.sort()[0].createdAt : a.createdAt;
@@ -221,7 +239,7 @@ export default function Index() {
<div className="hidden sm:block"> <div className="hidden sm:block">
<p className="text-sm text-neutral-700"> <p className="text-sm text-neutral-700">
Showing <span className="font-medium">{(page - 1) * 20}</span> to{" "} Showing <span className="font-medium">{(page - 1) * 20}</span> to{" "}
<span className="font-medium">{page * 20}</span> of <span className="font-medium">{contacts.count}</span>{" "} <span className="font-medium">{page * 20}</span> of <span className="font-medium">{filtered.length}</span>{" "}
contacts contacts
</p> </p>
</div> </div>
@@ -441,7 +459,7 @@ export default function Index() {
title={"Contacts"} title={"Contacts"}
description={"View and manage your contacts"} description={"View and manage your contacts"}
actions={ actions={
<div className={"grid w-full gap-3 md:w-fit md:grid-cols-2"}> <div className={"grid w-full gap-3 md:w-fit md:grid-cols-3"}>
<input <input
onChange={(e) => setQuery(e.target.value)} onChange={(e) => setQuery(e.target.value)}
autoComplete={"off"} autoComplete={"off"}
@@ -452,6 +470,16 @@ export default function Index() {
} }
/> />
<Dropdown
onChange={(v) => setStatusFilter(v)}
values={[
{ name: "All", value: "all" },
{ name: "Subscribed", value: "subscribed" },
{ name: "Unsubscribed", value: "unsubscribed" },
]}
selectedValue={statusFilter}
/>
<motion.button <motion.button
onClick={() => setContactModal(true)} onClick={() => setContactModal(true)}
whileHover={{ scale: 1.05 }} whileHover={{ scale: 1.05 }}