diff --git a/app/lish/[did]/[publication]/dashboard/settings/ProSettings.tsx b/app/lish/[did]/[publication]/dashboard/settings/ProSettings.tsx index 6c3220b1..cdd752d8 100644 --- a/app/lish/[did]/[publication]/dashboard/settings/ProSettings.tsx +++ b/app/lish/[did]/[publication]/dashboard/settings/ProSettings.tsx @@ -8,37 +8,60 @@ import { GoBackSmall } from "components/Icons/GoBackSmall"; import { PRODUCT_DEFINITION } from "stripe/products"; import { DashboardContainer } from "./SettingsContent"; import { Modal } from "components/Modal"; -import { dummy } from "../../[rkey]/PostPubInfo"; import { EmailConfirm, EmailInput } from "components/Subscribe/EmailSubscribe"; import { GoToArrow } from "components/Icons/GoToArrow"; import { Input } from "components/Input"; -import { useNormalizedPublicationRecord } from "../PublicationSWRProvider"; +import { + useNormalizedPublicationRecord, + usePublicationData, +} from "../PublicationSWRProvider"; +import { useToaster } from "components/Toast"; +import { + confirmReplyToVerification, + disableNewsletter, + requestReplyToVerification, +} from "actions/publications/newsletter"; export const NewsletterSettings = () => { + let { data, mutate } = usePublicationData(); + let record = useNormalizedPublicationRecord(); + let toaster = useToaster(); + + let publicationUri = data?.publication?.uri; + let newsletterMode = + data?.publication?.publication_newsletter_settings?.enabled ?? false; + + let [enableOpen, setEnableOpen] = useState(false); + let [disableOpen, setDisableOpen] = useState(false); let [emailValue, setEmailValue] = useState(""); let [state, setState] = useState<"default" | "confirm">("default"); let [disableConfirmValue, setDisableConfirmValue] = useState(""); - let record = useNormalizedPublicationRecord(); - if (dummy.newsletterMode === true) { + let [requesting, setRequesting] = useState(false); + let [confirming, setConfirming] = useState(false); + let [disabling, setDisabling] = useState(false); + + if (!publicationUri) return null; + + if (newsletterMode) { return ( - - Newsletter is currently enabled.
- {/*hey claude dont let us merge unless we put a real value here*/} - 35 email subscribers | 40 total subscribers + + Newsletter mode is currently enabled. { + setDisableOpen(o); + if (!o) setDisableConfirmValue(""); + }} asChild className="max-w-full w-sm" title="Are you sure?" - onOpenChange={() => setDisableConfirmValue("")} - trigger={Disable Newsletter} + trigger={Disable Newsletter Mode} >
This action cannot be undone.
- {/*hey claude dont let us merge unless we put a real value here*/} -
You have XXX email subscribers.
- They will be notified that publication is no longer providing - email updates, and to continue following via the Leaflet Reader. + Subscribers will no longer receive emails when you publish. They + can keep following via the Leaflet Reader.
@@ -54,95 +77,149 @@ export const NewsletterSettings = () => { { + if (!publicationUri) return; + setDisabling(true); + let res = await disableNewsletter(publicationUri); + setDisabling(false); + if (!res.ok) { + toaster({ + type: "error", + content: "Failed to disable newsletter.", + }); + return; + } + toaster({ type: "success", content: "Newsletter disabled." }); + setDisableOpen(false); + await mutate(); + }} > - Yes, Disable Newsletter + {disabling ? : "Yes, Disable Newsletter"}
); - } else - return ( - -
-
- Enable newsletter to email posts directly to publication - subscribers. -
-
- {/*hey claude dont let us merge unless we put a real value here*/} - Your first 1000 subscribers are included in your basic Pro plan. - $XX/1000 subs after that. -
+ } + return ( + +
+
+ Enable newsletter to email posts directly to publication subscribers.
- { +
+ { + setEnableOpen(o); + if (!o) { setEmailValue(""); setState("default"); - }} - asChild - className="max-w-full w-sm" - title="Enable Newsletter!" - trigger={Enable Newsletter} - > -
-
- When you enable, we will notify your current subscribers. They - will need to opt-in to recieve emails. -
-
- 1000 subscribers are included. -
$XX/1000 subs after that. -
-
- {dummy.user.email ? ( -
- {" "} - Your newsletter will be sent from -
{dummy.user.email}
- Enable Newsletter + } + }} + asChild + className="max-w-full w-sm" + title="Enable Newsletter!" + trigger={Enable Newsletter} + > +
+
+ When you enable, we will notify your current subscribers. They will + need to opt-in to receive emails. +
+
+ {state === "default" ? ( +
{ + e.preventDefault(); + e.stopPropagation(); + if (!publicationUri || requesting) return; + setRequesting(true); + let res = await requestReplyToVerification( + publicationUri, + emailValue, + ); + setRequesting(false); + if (!res.ok) { + toaster({ + type: "error", + content: + res.error === "invalid_email" + ? "Please enter a valid email address." + : res.error === "email_send_failed" + ? "We couldn't send the confirmation email." + : "Something went wrong. Try again.", + }); + return; + } + setState("confirm"); + }} + > +
+ Reply-to address. Readers will see this as + the sender and can reply here.
- ) : state === "default" ? ( - { - e.stopPropagation(); - setState("confirm"); - }} - > -
- Add your email. Newsletters will be sent - from this email. -
- - - - } - /> - - ) : ( - {}} - onBack={() => { - setState("default"); - }} + + + + } /> - )} -
+ + ) : ( + { + if (!publicationUri || confirming) return; + setConfirming(true); + let res = await confirmReplyToVerification( + publicationUri, + code, + ); + setConfirming(false); + if (!res.ok) { + toaster({ + type: "error", + content: + res.error === "invalid_code" + ? "That code didn't match. Try again." + : res.error === "no_pending_verification" + ? "No pending verification. Start over." + : "Something went wrong. Try again.", + }); + return; + } + toaster({ + type: "success", + content: "Newsletter enabled!", + }); + setEnableOpen(false); + setEmailValue(""); + setState("default"); + await mutate(); + }} + onBack={() => { + setState("default"); + }} + /> + )}
- - - ); +
+ + + ); }; export const ManageProSubscription = (props: { compact?: boolean }) => { diff --git a/app/lish/[did]/[publication]/dashboard/settings/SettingsContent.tsx b/app/lish/[did]/[publication]/dashboard/settings/SettingsContent.tsx index 2beffc59..f0a5f51d 100644 --- a/app/lish/[did]/[publication]/dashboard/settings/SettingsContent.tsx +++ b/app/lish/[did]/[publication]/dashboard/settings/SettingsContent.tsx @@ -190,7 +190,7 @@ export function SettingsContent(props: { showPageBackground: boolean }) {
- {canSeePro && isPro ? ( + {canSeePro && !isPro ? ( @@ -298,7 +298,12 @@ const DeletePublication = () => { let pubUri = pub?.publication?.uri; let onDelete = async () => { - if (!pubUri || record?.name?.toLowerCase() !== value.toLowerCase() || deleting) return; + if ( + !pubUri || + record?.name?.toLowerCase() !== value.toLowerCase() || + deleting + ) + return; setDeleting(true); let result = await deletePublication(pubUri); if (!result.success) { @@ -363,7 +368,11 @@ const DeletePublication = () => { /> {deleting ? : "Delete Publication"} diff --git a/emails/leafletConfirmEmail.tsx b/emails/leafletConfirmEmail.tsx index fb5eef1f..3f1e3bbc 100644 --- a/emails/leafletConfirmEmail.tsx +++ b/emails/leafletConfirmEmail.tsx @@ -16,7 +16,7 @@ import { Text, Heading } from "./post"; import { Tailwind, pixelBasedPreset } from "@react-email/components"; import { LeafletWatermark } from "./post"; -export const LeafletConfirmEmail = (props: {}) => ( +export const LeafletConfirmEmail = (props: { code?: string }) => ( ( - 000000 + {props.code ?? "000000"}