diff --git a/app/api/rpc/[command]/get_publication_data.ts b/app/api/rpc/[command]/get_publication_data.ts index e0db6852..fdef74ce 100644 --- a/app/api/rpc/[command]/get_publication_data.ts +++ b/app/api/rpc/[command]/get_publication_data.ts @@ -44,6 +44,7 @@ export const get_publication_data = makeRoute({ recommends_on_documents(count) )), publication_subscriptions(*, identities(bsky_profiles(*))), + publication_email_subscribers(*, identities(atp_did, bsky_profiles(*))), publication_domains(*), publication_newsletter_settings(enabled), leaflets_in_publications(*, diff --git a/app/lish/[did]/[publication]/dashboard/PublicationSubscribers.tsx b/app/lish/[did]/[publication]/dashboard/PublicationSubscribers.tsx index 0ccd083b..f827484f 100644 --- a/app/lish/[did]/[publication]/dashboard/PublicationSubscribers.tsx +++ b/app/lish/[did]/[publication]/dashboard/PublicationSubscribers.tsx @@ -1,5 +1,4 @@ "use client"; -import { AppBskyActorProfile } from "lexicons/api"; import { usePublicationData } from "./PublicationSWRProvider"; import { ButtonPrimary } from "components/Buttons"; import { getPublicationURL } from "app/lish/createPub/getPublicationURL"; @@ -7,27 +6,63 @@ import { useSmoker } from "components/Toast"; import { Menu, MenuItem } from "components/Menu"; import { Separator } from "components/Layout"; import { MoreOptionsVerticalTiny } from "components/Icons/MoreOptionsVerticalTiny"; -import { Checkbox } from "components/Checkbox"; -import { useEffect, useState } from "react"; import { useLocalizedDate } from "src/hooks/useLocalizedDate"; type subscriber = { email: string | undefined; did: string | undefined }; -// HELLO! THIS FILE HAS CHECKBOXES AND A HEADER COMMENTED OUT -// the checkboxes would let you select users and and the eader provided a count and let you select all and do actions -// I also removed some props from SubscriberListItem around emails since we dont have them yet. -// WHen we get emails in, we can uncomment some of this stuff +type MergedSubscriber = { + key: string; + did: string | undefined; + handle: string | undefined; + email: string | undefined; + created_at: string; +}; export function PublicationSubscribers(props: { showPageBackground?: boolean; }) { let smoker = useSmoker(); let { data: publication } = usePublicationData(); - // let [checkedSubscribers, setCheckedSubscribers] = useState([]); - // let [checkAll, setCheckAll] = useState(false); if (!publication) return
null
; - let subscribers = publication.publication?.publication_subscriptions || []; + let atprotoSubs = publication.publication?.publication_subscriptions || []; + let newsletterEnabled = + !!publication.publication?.publication_newsletter_settings?.enabled; + let emailSubs = newsletterEnabled + ? (publication.publication?.publication_email_subscribers || []).filter( + (s) => s.state === "confirmed", + ) + : []; + + let byDid = new Map(); + let emailOnly: MergedSubscriber[] = []; + for (let s of atprotoSubs) { + let did = s.identities?.bsky_profiles?.did; + if (!did) continue; + byDid.set(did, { + key: `did:${did}`, + did, + handle: s.identities?.bsky_profiles?.handle ?? undefined, + email: undefined, + created_at: s.created_at, + }); + } + for (let s of emailSubs) { + let linkedDid = s.identities?.atp_did ?? undefined; + let existing = linkedDid ? byDid.get(linkedDid) : undefined; + if (existing) { + existing.email = s.email; + continue; + } + emailOnly.push({ + key: `email:${s.id}`, + did: linkedDid, + handle: s.identities?.bsky_profiles?.handle ?? undefined, + email: s.email, + created_at: s.created_at, + }); + } + let subscribers: MergedSubscriber[] = [...byDid.values(), ...emailOnly]; // useEffect(() => { // const allSubscribersSelected = subscribers.every((subscriber) => @@ -123,25 +158,16 @@ export function PublicationSubscribers(props: {
{subscribers - .sort((a, b) => { - return b.created_at.localeCompare(a.created_at); - }) - .map((subscriber, index) => { - if (!subscriber.identities?.bsky_profiles) return null; - let handle = subscriber.identities?.bsky_profiles.handle; - let did = subscriber.identities?.bsky_profiles.did; - let profile = subscriber.identities?.bsky_profiles - ?.record as AppBskyActorProfile.Record | null; - if (!profile) return null; - return ( - - ); - })} + .sort((a, b) => b.created_at.localeCompare(a.created_at)) + .map((subscriber) => ( + + ))}
); @@ -150,59 +176,34 @@ export function PublicationSubscribers(props: { const SubscriberListItem = (props: { handle: string | undefined; did: string | undefined; + email: string | undefined; createdAt: string; }) => { return ( - // { - // if (props.checked === false) { - // const newCheckedSubscribers = [ - // ...props.checkedSubscribers, - // { - // email: props.email, - // did: props.did, - // }, - // ]; - // props.setCheckedSubscribers(newCheckedSubscribers); - // } else { - // const newCheckedSubscribers = props.checkedSubscribers.filter( - // (subscriber) => - // !( - // subscriber.email === props.email && subscriber.did === props.did - // ), - // ); - // props.setCheckedSubscribers(newCheckedSubscribers); - // } - // }} - // > - <> -
- {/* - {props.email} - - - {props.handle && props.email && ( - - )}*/} - {props.handle && ( - - @{props.handle} - - )} - -
- - //
+
+ {props.handle && ( + + @{props.handle} + + )} + {props.handle && props.email && ( + + )} + {props.email && ( + + {props.email} + + )} + +
); };