From 115ac5fe6c87181fe33de367d88d01ef872ed2af Mon Sep 17 00:00:00 2001 From: Himanshu Ahuja <106527952+himanshu-ntml@users.noreply.github.com> Date: Tue, 3 Jun 2025 18:12:10 -0400 Subject: [PATCH 1/2] fix: return updated contact info --- packages/api/src/controllers/v1/Contacts.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/api/src/controllers/v1/Contacts.ts b/packages/api/src/controllers/v1/Contacts.ts index 7389975..0cfdfb4 100644 --- a/packages/api/src/controllers/v1/Contacts.ts +++ b/packages/api/src/controllers/v1/Contacts.ts @@ -248,12 +248,17 @@ export class Contacts { const { id, email, subscribed, data } = ContactSchemas.manage.parse(req.body); - const contact = id ? await ContactService.id(id) : await ContactService.email(project.id, email as string); + let contact = id ? await ContactService.id(id) : await ContactService.email(project.id, email as string); if (!contact || contact.projectId !== project.id) { throw new NotFound("contact"); } + const updateData: Record = { + email, + subscribed: subscribed ?? contact.subscribed, + }; + if (data) { const givenUserData = Object.entries(data); const dataToUpdate = JSON.parse(contact.data ?? "{}"); @@ -266,18 +271,12 @@ export class Contacts { } }); - await prisma.contact.update({ - where: { id: contact.id }, - data: { data: JSON.stringify(dataToUpdate) }, - }); + updateData.data = JSON.stringify(dataToUpdate); } - await prisma.contact.update({ + contact = await prisma.contact.update({ where: { id: contact.id }, - data: { - email, - subscribed: subscribed ?? contact.subscribed, - }, + data: updateData, }); await redis.del(Keys.Project.contacts(project.id)); From 45697cf6b122266ec3ab35e51e064db48517448d Mon Sep 17 00:00:00 2001 From: Himanshu Ahuja <106527952+himanshu-ntml@users.noreply.github.com> Date: Tue, 3 Jun 2025 18:48:27 -0400 Subject: [PATCH 2/2] feat(dashboard): add status filter for contacts --- .../dashboard/src/pages/contacts/index.tsx | 184 ++++++++++-------- 1 file changed, 106 insertions(+), 78 deletions(-) diff --git a/packages/dashboard/src/pages/contacts/index.tsx b/packages/dashboard/src/pages/contacts/index.tsx index 46b6930..ce59060 100644 --- a/packages/dashboard/src/pages/contacts/index.tsx +++ b/packages/dashboard/src/pages/contacts/index.tsx @@ -9,7 +9,7 @@ import React, { useState } from "react"; import { type FieldError, useFieldArray, useForm } from "react-hook-form"; import { toast } from "sonner"; 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 { searchContacts, useContacts } from "../../lib/hooks/contacts"; import { useActiveProject } from "../../lib/hooks/projects"; @@ -31,8 +31,9 @@ interface ContactValues { * */ export default function Index() { - const [page, setPage] = useState(1); - const [query, setQuery] = useState(); + const [page, setPage] = useState(1); + const [query, setQuery] = useState(); + const [statusFilter, setStatusFilter] = useState("all"); const project = useActiveProject(); const { data: user } = useUser(); @@ -125,47 +126,56 @@ export default function Index() { return ; } - if (search && query !== undefined) { - if (search.contacts.length > 0) { - return ( - <> - { - const aTrigger = a.triggers.length > 0 ? a.triggers.sort()[0].createdAt : a.createdAt; + if (search && query !== undefined) { + const filtered = search.contacts + .filter((c) => + statusFilter === "all" + ? true + : statusFilter === "subscribed" + ? c.subscribed + : !c.subscribed, + ); - const bTrigger = b.triggers.length > 0 ? b.triggers.sort()[0].createdAt : b.createdAt; + if (filtered.length > 0) { + return ( + <> +
{ + const aTrigger = a.triggers.length > 0 ? a.triggers.sort()[0].createdAt : a.createdAt; - return bTrigger > aTrigger ? 1 : -1; - }) - .map((u) => { - return { - Email: u.email, - "Last Activity": dayjs() - .to( - [...u.triggers, ...u.emails].length > 0 - ? [...u.triggers, ...u.emails].sort((a, b) => { - return a.createdAt > b.createdAt ? -1 : 1; - })[0].createdAt - : u.createdAt, - ) - .toString(), - Subscribed: u.subscribed, - Edit: ( - - - - ), - }; - })} - /> - - ); - } - return ( - <> - 0 ? b.triggers.sort()[0].createdAt : b.createdAt; + + return bTrigger > aTrigger ? 1 : -1; + }) + .map((u) => { + return { + Email: u.email, + "Last Activity": dayjs() + .to( + [...u.triggers, ...u.emails].length > 0 + ? [...u.triggers, ...u.emails].sort((a, b) => { + return a.createdAt > b.createdAt ? -1 : 1; + })[0].createdAt + : u.createdAt, + ) + .toString(), + Subscribed: u.subscribed, + Edit: ( + + + + ), + }; + })} + /> + + ); + } + return ( + <> + 0) { - return ( - <> -
{ - const aTrigger = a.triggers.length > 0 ? a.triggers.sort()[0].createdAt : a.createdAt; + if (contacts) { + const filtered = contacts.contacts.filter((c) => + statusFilter === "all" + ? true + : statusFilter === "subscribed" + ? c.subscribed + : !c.subscribed, + ); - const bTrigger = b.triggers.length > 0 ? b.triggers.sort()[0].createdAt : b.createdAt; + if (filtered.length > 0) { + return ( + <> +
{ + const aTrigger = a.triggers.length > 0 ? a.triggers.sort()[0].createdAt : a.createdAt; + + const bTrigger = b.triggers.length > 0 ? b.triggers.sort()[0].createdAt : b.createdAt; return bTrigger > aTrigger ? 1 : -1; - }) - .map((u) => { - return { - Email: u.email, - "Last Activity": dayjs() - .to( + }) + .map((u) => { + return { + Email: u.email, + "Last Activity": dayjs() + .to( u.triggers.length > 0 ? u.triggers.sort((a, b) => { return a.createdAt > b.createdAt ? -1 : 1; @@ -215,16 +233,16 @@ export default function Index() { ), }; - })} - /> -