import { zodResolver } from "@hookform/resolvers/zod"; import { ContactSchemas } from "@plunk/shared"; import type { Template } from "@prisma/client"; import dayjs from "dayjs"; import { AnimatePresence, motion } from "framer-motion"; import { Edit2, Plus } from "lucide-react"; import Link from "next/link"; 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 { Dashboard } from "../../layouts"; import { searchContacts, useContacts } from "../../lib/hooks/contacts"; import { useActiveProject } from "../../lib/hooks/projects"; import { useUser } from "../../lib/hooks/users"; import { network } from "../../lib/network"; interface ContactValues { email: string; data?: | { [x: string]: string | string[]; } | null | undefined; subscribed: boolean; } /** * */ export default function Index() { const [page, setPage] = useState(1); const [query, setQuery] = useState(); const project = useActiveProject(); const { data: user } = useUser(); const { data: contacts, mutate } = useContacts(page); const { data: search } = searchContacts(query); const [contactModal, setContactModal] = useState(false); const { register, handleSubmit, formState: { errors }, reset, watch, setValue, } = useForm({ resolver: zodResolver(ContactSchemas.create), defaultValues: { subscribed: true, }, }); const { register: dataRegister, control, getValues: getDataValues, reset: dataReset, } = useForm({ resolver: zodResolver( z.object({ data: z .array( z.object({ value: z.object({ key: z.string(), value: z.string() }), }), ) .min(0), }), ), defaultValues: { data: [{ value: { key: "", value: "" } }], }, }); const { fields, append: fieldAppend, remove: fieldRemove } = useFieldArray({ control, name: "data" }); if (!project || !user) { return ; } const create = (data: ContactValues) => { const entries = getDataValues().data.map(({ value }) => [value.key, value.value]); let dataObject = {}; entries.forEach(([key, value]) => { Object.assign(dataObject, { [key]: value }); }); dataObject = Object.fromEntries(Object.entries(dataObject).filter(([, value]) => value !== "")); toast.promise( network.mock(project.secret, "POST", "/v1/contacts", { ...data, subscribed: true, data: dataObject, }), { loading: "Creating new contact", success: () => { void mutate(); reset(); return "Created new contacts"; }, error: "Could not create new contact!", }, ); reset(); dataReset(); setContactModal(false); }; const renderContacts = () => { if (!contacts && !search) { return ; } if (query && !search) { return ; } if (search && query !== undefined) { if (search.contacts.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( [...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 ( <> } title={"No contacts found"} description={`Your query ${query} did not return any contacts`} /> ); } if (contacts) { if (contacts.contacts.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( u.triggers.length > 0 ? u.triggers.sort((a, b) => { return a.createdAt > b.createdAt ? -1 : 1; })[0].createdAt : u.createdAt, ) .toString(), Subscribed: u.subscribed, Edit: ( ), }; })} /> ); } return ( <> ); } }; return ( <> setContactModal(!contactModal)} onAction={handleSubmit(create)} type={"info"} action={"Create"} title={"Create new contact"} >
{errors.email?.message && ( {errors.email.message} )}
{fields.length > 0 ? ( fields.map((field, index) => { // @ts-ignore return ( <>
); }) ) : (

No fields added

)}
{(errors.data as FieldError | undefined)?.message && ( {(errors.data as FieldError | undefined)?.message} )}
setValue("subscribed", !watch("subscribed"))} />
setQuery(e.target.value)} autoComplete={"off"} type="search" placeholder={"Search email or metadata"} className={ "rounded border-neutral-300 transition ease-in-out focus:border-neutral-800 focus:ring-neutral-800 sm:text-sm" } /> setContactModal(true)} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.9 }} className={ "flex items-center justify-center gap-x-1 rounded bg-neutral-800 px-8 py-2 text-center text-sm font-medium text-white" } > New } > {renderContacts()} ); }