payload-subscribers-plugin 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +305 -0
- package/dist/collections/OptInChannels.d.ts +3 -0
- package/dist/collections/OptInChannels.js +44 -0
- package/dist/collections/OptInChannels.js.map +1 -0
- package/dist/collections/Subscribers.d.ts +8 -0
- package/dist/collections/Subscribers.js +88 -0
- package/dist/collections/Subscribers.js.map +1 -0
- package/dist/collections/fields/OptedInChannels.d.ts +2 -0
- package/dist/collections/fields/OptedInChannels.js +12 -0
- package/dist/collections/fields/OptedInChannels.js.map +1 -0
- package/dist/components/BeforeDashboardClient.d.ts +1 -0
- package/dist/components/BeforeDashboardClient.js +40 -0
- package/dist/components/BeforeDashboardClient.js.map +1 -0
- package/dist/components/BeforeDashboardServer.d.ts +2 -0
- package/dist/components/BeforeDashboardServer.js +22 -0
- package/dist/components/BeforeDashboardServer.js.map +1 -0
- package/dist/components/BeforeDashboardServer.module.css +5 -0
- package/dist/components/app/RequestMagicLink.d.ts +16 -0
- package/dist/components/app/RequestMagicLink.js +114 -0
- package/dist/components/app/RequestMagicLink.js.map +1 -0
- package/dist/components/app/RequestMagicLink.module.css +5 -0
- package/dist/components/app/RequestOrSubscribe.d.ts +17 -0
- package/dist/components/app/RequestOrSubscribe.js +28 -0
- package/dist/components/app/RequestOrSubscribe.js.map +1 -0
- package/dist/components/app/SelectOptInChannels.d.ts +20 -0
- package/dist/components/app/SelectOptInChannels.js +120 -0
- package/dist/components/app/SelectOptInChannels.js.map +1 -0
- package/dist/components/app/SelectOptInChannels.module.css +5 -0
- package/dist/components/app/Subscribe.d.ts +18 -0
- package/dist/components/app/Subscribe.js +169 -0
- package/dist/components/app/Subscribe.js.map +1 -0
- package/dist/components/app/Subscribe.module.css +5 -0
- package/dist/components/app/SubscriberMenu.d.ts +7 -0
- package/dist/components/app/SubscriberMenu.js +44 -0
- package/dist/components/app/SubscriberMenu.js.map +1 -0
- package/dist/components/app/VerifyMagicLink.d.ts +23 -0
- package/dist/components/app/VerifyMagicLink.js +169 -0
- package/dist/components/app/VerifyMagicLink.js.map +1 -0
- package/dist/components/app/VerifyMagicLink.module.css +5 -0
- package/dist/components/app/helpers.d.ts +1 -0
- package/dist/components/app/helpers.js +5 -0
- package/dist/components/app/helpers.js.map +1 -0
- package/dist/components/app/shared.module.css +14 -0
- package/dist/contexts/SubscriberProvider.d.ts +15 -0
- package/dist/contexts/SubscriberProvider.js +105 -0
- package/dist/contexts/SubscriberProvider.js.map +1 -0
- package/dist/copied/payload-types.d.ts +395 -0
- package/dist/copied/payload-types.js +15 -0
- package/dist/copied/payload-types.js.map +1 -0
- package/dist/copied/payload.config.d.ts +2 -0
- package/dist/endpoints/customEndpointHandler.d.ts +2 -0
- package/dist/endpoints/customEndpointHandler.js +7 -0
- package/dist/endpoints/customEndpointHandler.js.map +1 -0
- package/dist/endpoints/getOptInChannels.d.ts +19 -0
- package/dist/endpoints/getOptInChannels.js +42 -0
- package/dist/endpoints/getOptInChannels.js.map +1 -0
- package/dist/endpoints/logout.d.ts +20 -0
- package/dist/endpoints/logout.js +60 -0
- package/dist/endpoints/logout.js.map +1 -0
- package/dist/endpoints/requestMagicLink.d.ts +20 -0
- package/dist/endpoints/requestMagicLink.js +122 -0
- package/dist/endpoints/requestMagicLink.js.map +1 -0
- package/dist/endpoints/subscribe.d.ts +24 -0
- package/dist/endpoints/subscribe.js +343 -0
- package/dist/endpoints/subscribe.js.map +1 -0
- package/dist/endpoints/subscriberAuth.d.ts +22 -0
- package/dist/endpoints/subscriberAuth.js +69 -0
- package/dist/endpoints/subscriberAuth.js.map +1 -0
- package/dist/endpoints/verifyMagicLink.d.ts +20 -0
- package/dist/endpoints/verifyMagicLink.js +142 -0
- package/dist/endpoints/verifyMagicLink.js.map +1 -0
- package/dist/exports/client.d.ts +1 -0
- package/dist/exports/client.js +3 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/index.d.ts +1 -0
- package/dist/exports/index.js +3 -0
- package/dist/exports/index.js.map +1 -0
- package/dist/exports/rsc.d.ts +1 -0
- package/dist/exports/rsc.js +3 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/exports/ui.d.ts +11 -0
- package/dist/exports/ui.js +9 -0
- package/dist/exports/ui.js.map +1 -0
- package/dist/helpers/serverConfig.d.ts +4 -0
- package/dist/helpers/serverConfig.js +22 -0
- package/dist/helpers/serverConfig.js.map +1 -0
- package/dist/helpers/testData.d.ts +2 -0
- package/dist/helpers/testData.js +4 -0
- package/dist/helpers/testData.js.map +1 -0
- package/dist/helpers/token.d.ts +9 -0
- package/dist/helpers/token.js +20 -0
- package/dist/helpers/token.js.map +1 -0
- package/dist/helpers/verifyOptIns.d.ts +5 -0
- package/dist/helpers/verifyOptIns.js +33 -0
- package/dist/helpers/verifyOptIns.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +147 -0
- package/dist/index.js.map +1 -0
- package/dist/react-hooks/useServerUrl.d.ts +3 -0
- package/dist/react-hooks/useServerUrl.js +19 -0
- package/dist/react-hooks/useServerUrl.js.map +1 -0
- package/dist/server-functions/serverUrl.d.ts +3 -0
- package/dist/server-functions/serverUrl.js +31 -0
- package/dist/server-functions/serverUrl.js.map +1 -0
- package/dist/server-functions/subscriberAuth.d.ts +11 -0
- package/package.json +94 -0
- package/src/collections/OptInChannels.ts +45 -0
- package/src/collections/Subscribers.ts +99 -0
- package/src/collections/fields/OptedInChannels.ts +12 -0
- package/src/components/app/RequestMagicLink.tsx +129 -0
- package/src/components/app/RequestOrSubscribe.tsx +58 -0
- package/src/components/app/SelectOptInChannels.tsx +147 -0
- package/src/components/app/Subscribe.tsx +190 -0
- package/src/components/app/SubscriberMenu.tsx +46 -0
- package/src/components/app/VerifyMagicLink.tsx +197 -0
- package/src/components/app/helpers.ts +6 -0
- package/src/components/app/shared.module.css +14 -0
- package/src/contexts/SubscriberProvider.tsx +122 -0
- package/src/copied/payload-types.ts +478 -0
- package/src/endpoints/getOptInChannels.ts +56 -0
- package/src/endpoints/logout.ts +104 -0
- package/src/endpoints/requestMagicLink.ts +139 -0
- package/src/endpoints/subscribe.ts +435 -0
- package/src/endpoints/subscriberAuth.ts +100 -0
- package/src/endpoints/verifyMagicLink.ts +164 -0
- package/src/exports/index.ts +1 -0
- package/src/exports/ui.ts +17 -0
- package/src/helpers/testData.ts +2 -0
- package/src/helpers/token.ts +14 -0
- package/src/helpers/verifyOptIns.ts +39 -0
- package/src/index.ts +207 -0
- package/src/react-hooks/useServerUrl.tsx +18 -0
- package/src/server-functions/serverUrl.ts +38 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { PayloadSDK } from '@payloadcms/sdk';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useSubscriber } from '../../contexts/SubscriberProvider.js';
|
|
6
|
+
import { useServerUrl } from '../../react-hooks/useServerUrl.js';
|
|
7
|
+
import { mergeClassNames } from './helpers.js';
|
|
8
|
+
import styles from './shared.module.css';
|
|
9
|
+
export const RequestMagicLink = ({ classNames = {
|
|
10
|
+
button: '',
|
|
11
|
+
container: '',
|
|
12
|
+
emailInput: '',
|
|
13
|
+
error: '',
|
|
14
|
+
form: '',
|
|
15
|
+
message: ''
|
|
16
|
+
}, handleMagicLinkRequested })=>{
|
|
17
|
+
const { subscriber } = useSubscriber();
|
|
18
|
+
const { serverURL } = useServerUrl();
|
|
19
|
+
const [status, setStatus] = useState('default');
|
|
20
|
+
const sdk = new PayloadSDK({
|
|
21
|
+
baseURL: serverURL || ''
|
|
22
|
+
});
|
|
23
|
+
const [result, setResult] = useState();
|
|
24
|
+
const [email, setEmail] = useState(subscriber?.email || '');
|
|
25
|
+
useEffect(()=>{
|
|
26
|
+
setEmail(subscriber?.email || '');
|
|
27
|
+
}, [
|
|
28
|
+
subscriber
|
|
29
|
+
]);
|
|
30
|
+
const handleSubmit = async (e)=>{
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
const forwardUrl = window.location.pathname + '?now=' + new Date().toISOString();
|
|
33
|
+
const emailTokenResponse = await sdk.request({
|
|
34
|
+
json: {
|
|
35
|
+
email,
|
|
36
|
+
forwardUrl
|
|
37
|
+
},
|
|
38
|
+
method: 'POST',
|
|
39
|
+
path: '/api/emailToken'
|
|
40
|
+
});
|
|
41
|
+
if (emailTokenResponse.ok) {
|
|
42
|
+
const emailTokenResponseJson = await emailTokenResponse.json();
|
|
43
|
+
if (handleMagicLinkRequested) {
|
|
44
|
+
handleMagicLinkRequested(emailTokenResponseJson);
|
|
45
|
+
}
|
|
46
|
+
// @ts-expect-error One or the other exists
|
|
47
|
+
const { emailResult, error } = emailTokenResponseJson;
|
|
48
|
+
if (error) {
|
|
49
|
+
setStatus('error');
|
|
50
|
+
setResult(`An error occured. Please try again. \n ${error}`);
|
|
51
|
+
} else if (emailResult) {
|
|
52
|
+
setStatus('sent');
|
|
53
|
+
setResult('An email has been sent containing your magic link.');
|
|
54
|
+
} else {
|
|
55
|
+
setStatus('error');
|
|
56
|
+
setResult(`An error occured. Please try again. \nResult unknown`);
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
const emailTokenResponseText = await emailTokenResponse.text();
|
|
60
|
+
setStatus('error');
|
|
61
|
+
setResult(`An error occured. Please try again. \n${emailTokenResponseText}`);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
65
|
+
className: mergeClassNames([
|
|
66
|
+
styles.container,
|
|
67
|
+
classNames.container
|
|
68
|
+
]),
|
|
69
|
+
children: [
|
|
70
|
+
result ? /*#__PURE__*/ _jsx("p", {
|
|
71
|
+
className: mergeClassNames([
|
|
72
|
+
styles.message,
|
|
73
|
+
classNames.message,
|
|
74
|
+
status == 'error' ? [
|
|
75
|
+
styles.error,
|
|
76
|
+
classNames.error
|
|
77
|
+
] : []
|
|
78
|
+
]),
|
|
79
|
+
children: result
|
|
80
|
+
}) : /*#__PURE__*/ _jsx(_Fragment, {}),
|
|
81
|
+
/*#__PURE__*/ _jsxs("form", {
|
|
82
|
+
className: mergeClassNames([
|
|
83
|
+
styles.form,
|
|
84
|
+
classNames.form
|
|
85
|
+
]),
|
|
86
|
+
method: "POST",
|
|
87
|
+
onSubmit: handleSubmit,
|
|
88
|
+
children: [
|
|
89
|
+
/*#__PURE__*/ _jsx("input", {
|
|
90
|
+
"aria-label": "enter your email",
|
|
91
|
+
className: mergeClassNames([
|
|
92
|
+
styles.emailInput,
|
|
93
|
+
classNames.emailInput
|
|
94
|
+
]),
|
|
95
|
+
onChange: (e)=>setEmail(e.target.value),
|
|
96
|
+
placeholder: "enter your email",
|
|
97
|
+
type: "email",
|
|
98
|
+
value: email
|
|
99
|
+
}),
|
|
100
|
+
/*#__PURE__*/ _jsx("button", {
|
|
101
|
+
className: mergeClassNames([
|
|
102
|
+
styles.button,
|
|
103
|
+
classNames.button
|
|
104
|
+
]),
|
|
105
|
+
type: "submit",
|
|
106
|
+
children: "Request magic link"
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
})
|
|
110
|
+
]
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=RequestMagicLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/app/RequestMagicLink.tsx"],"sourcesContent":["'use client'\n\nimport { PayloadSDK } from '@payloadcms/sdk'\nimport { type ChangeEvent, type SubmitEvent, useEffect, useState } from 'react'\n\nimport type { Config } from '../../copied/payload-types.js'\nimport type { RequestMagicLinkResponse } from '../../endpoints/requestMagicLink.js'\n\nimport { useSubscriber } from '../../contexts/SubscriberProvider.js'\nimport { useServerUrl } from '../../react-hooks/useServerUrl.js'\nimport { mergeClassNames } from './helpers.js'\nimport styles from './shared.module.css'\n\nexport { RequestMagicLinkResponse }\n\nexport interface IRequestMagicLink {\n classNames?: RequestMagicLinkClasses\n handleMagicLinkRequested?: (result: RequestMagicLinkResponse) => void\n props?: any\n}\n\nexport type RequestMagicLinkClasses = {\n button?: string\n container?: string\n emailInput?: string\n error?: string\n form?: string\n message?: string\n}\n\ntype statusValues = 'default' | 'error' | 'sent'\n\nexport const RequestMagicLink = ({\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n message: '',\n },\n handleMagicLinkRequested,\n}: IRequestMagicLink) => {\n const { subscriber } = useSubscriber()\n const { serverURL } = useServerUrl()\n\n const [status, setStatus] = useState<statusValues>('default')\n\n const sdk = new PayloadSDK<Config>({\n baseURL: serverURL || '',\n })\n\n const [result, setResult] = useState<string>()\n const [email, setEmail] = useState(subscriber?.email || '')\n\n useEffect(() => {\n setEmail(subscriber?.email || '')\n }, [subscriber])\n\n const handleSubmit = async (e: SubmitEvent<HTMLFormElement>) => {\n e.preventDefault()\n const forwardUrl = window.location.pathname + '?now=' + new Date().toISOString()\n const emailTokenResponse = await sdk.request({\n json: {\n email,\n forwardUrl,\n },\n method: 'POST',\n path: '/api/emailToken',\n })\n if (emailTokenResponse.ok) {\n const emailTokenResponseJson: RequestMagicLinkResponse = await emailTokenResponse.json()\n if (handleMagicLinkRequested) {\n handleMagicLinkRequested(emailTokenResponseJson)\n }\n // @ts-expect-error One or the other exists\n const { emailResult, error } = emailTokenResponseJson\n if (error) {\n setStatus('error')\n setResult(`An error occured. Please try again. \\n ${error}`)\n } else if (emailResult) {\n setStatus('sent')\n setResult('An email has been sent containing your magic link.')\n } else {\n setStatus('error')\n setResult(`An error occured. Please try again. \\nResult unknown`)\n }\n } else {\n const emailTokenResponseText = await emailTokenResponse.text()\n setStatus('error')\n setResult(`An error occured. Please try again. \\n${emailTokenResponseText}`)\n }\n }\n\n return (\n <div className={mergeClassNames([styles.container, classNames.container])}>\n {result ? (\n <p\n className={mergeClassNames([\n styles.message,\n classNames.message,\n status == 'error' ? [styles.error, classNames.error] : [],\n ])}\n >\n {result}\n </p>\n ) : (\n <></>\n )}\n <form\n className={mergeClassNames([styles.form, classNames.form])}\n method=\"POST\"\n onSubmit={handleSubmit}\n >\n <input\n aria-label=\"enter your email\"\n className={mergeClassNames([styles.emailInput, classNames.emailInput])}\n onChange={(e: ChangeEvent<HTMLInputElement>) => setEmail(e.target.value)}\n placeholder=\"enter your email\"\n type=\"email\"\n value={email}\n />\n <button className={mergeClassNames([styles.button, classNames.button])} type=\"submit\">\n Request magic link\n </button>\n </form>\n </div>\n )\n}\n"],"names":["PayloadSDK","useEffect","useState","useSubscriber","useServerUrl","mergeClassNames","styles","RequestMagicLink","classNames","button","container","emailInput","error","form","message","handleMagicLinkRequested","subscriber","serverURL","status","setStatus","sdk","baseURL","result","setResult","email","setEmail","handleSubmit","e","preventDefault","forwardUrl","window","location","pathname","Date","toISOString","emailTokenResponse","request","json","method","path","ok","emailTokenResponseJson","emailResult","emailTokenResponseText","text","div","className","p","onSubmit","input","aria-label","onChange","target","value","placeholder","type"],"mappings":"AAAA;;AAEA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAA6CC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAK/E,SAASC,aAAa,QAAQ,uCAAsC;AACpE,SAASC,YAAY,QAAQ,oCAAmC;AAChE,SAASC,eAAe,QAAQ,eAAc;AAC9C,OAAOC,YAAY,sBAAqB;AAqBxC,OAAO,MAAMC,mBAAmB,CAAC,EAC/BC,aAAa;IACXC,QAAQ;IACRC,WAAW;IACXC,YAAY;IACZC,OAAO;IACPC,MAAM;IACNC,SAAS;AACX,CAAC,EACDC,wBAAwB,EACN;IAClB,MAAM,EAAEC,UAAU,EAAE,GAAGb;IACvB,MAAM,EAAEc,SAAS,EAAE,GAAGb;IAEtB,MAAM,CAACc,QAAQC,UAAU,GAAGjB,SAAuB;IAEnD,MAAMkB,MAAM,IAAIpB,WAAmB;QACjCqB,SAASJ,aAAa;IACxB;IAEA,MAAM,CAACK,QAAQC,UAAU,GAAGrB;IAC5B,MAAM,CAACsB,OAAOC,SAAS,GAAGvB,SAASc,YAAYQ,SAAS;IAExDvB,UAAU;QACRwB,SAAST,YAAYQ,SAAS;IAChC,GAAG;QAACR;KAAW;IAEf,MAAMU,eAAe,OAAOC;QAC1BA,EAAEC,cAAc;QAChB,MAAMC,aAAaC,OAAOC,QAAQ,CAACC,QAAQ,GAAG,UAAU,IAAIC,OAAOC,WAAW;QAC9E,MAAMC,qBAAqB,MAAMf,IAAIgB,OAAO,CAAC;YAC3CC,MAAM;gBACJb;gBACAK;YACF;YACAS,QAAQ;YACRC,MAAM;QACR;QACA,IAAIJ,mBAAmBK,EAAE,EAAE;YACzB,MAAMC,yBAAmD,MAAMN,mBAAmBE,IAAI;YACtF,IAAItB,0BAA0B;gBAC5BA,yBAAyB0B;YAC3B;YACA,2CAA2C;YAC3C,MAAM,EAAEC,WAAW,EAAE9B,KAAK,EAAE,GAAG6B;YAC/B,IAAI7B,OAAO;gBACTO,UAAU;gBACVI,UAAU,CAAC,uCAAuC,EAAEX,OAAO;YAC7D,OAAO,IAAI8B,aAAa;gBACtBvB,UAAU;gBACVI,UAAU;YACZ,OAAO;gBACLJ,UAAU;gBACVI,UAAU,CAAC,oDAAoD,CAAC;YAClE;QACF,OAAO;YACL,MAAMoB,yBAAyB,MAAMR,mBAAmBS,IAAI;YAC5DzB,UAAU;YACVI,UAAU,CAAC,sCAAsC,EAAEoB,wBAAwB;QAC7E;IACF;IAEA,qBACE,MAACE;QAAIC,WAAWzC,gBAAgB;YAACC,OAAOI,SAAS;YAAEF,WAAWE,SAAS;SAAC;;YACrEY,uBACC,KAACyB;gBACCD,WAAWzC,gBAAgB;oBACzBC,OAAOQ,OAAO;oBACdN,WAAWM,OAAO;oBAClBI,UAAU,UAAU;wBAACZ,OAAOM,KAAK;wBAAEJ,WAAWI,KAAK;qBAAC,GAAG,EAAE;iBAC1D;0BAEAU;+BAGH;0BAEF,MAACT;gBACCiC,WAAWzC,gBAAgB;oBAACC,OAAOO,IAAI;oBAAEL,WAAWK,IAAI;iBAAC;gBACzDyB,QAAO;gBACPU,UAAUtB;;kCAEV,KAACuB;wBACCC,cAAW;wBACXJ,WAAWzC,gBAAgB;4BAACC,OAAOK,UAAU;4BAAEH,WAAWG,UAAU;yBAAC;wBACrEwC,UAAU,CAACxB,IAAqCF,SAASE,EAAEyB,MAAM,CAACC,KAAK;wBACvEC,aAAY;wBACZC,MAAK;wBACLF,OAAO7B;;kCAET,KAACf;wBAAOqC,WAAWzC,gBAAgB;4BAACC,OAAOG,MAAM;4BAAED,WAAWC,MAAM;yBAAC;wBAAG8C,MAAK;kCAAS;;;;;;AAM9F,EAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type RequestMagicLinkResponse, type SubscribeResponse } from '../../exports/ui.js';
|
|
2
|
+
export type { RequestMagicLinkResponse, SubscribeResponse };
|
|
3
|
+
export type RequestOrSubscribeClasses = {
|
|
4
|
+
button?: string;
|
|
5
|
+
container?: string;
|
|
6
|
+
emailInput?: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
form?: string;
|
|
9
|
+
loading?: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
section?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function RequestOrSubscribe({ classNames, handleMagicLinkRequested, handleSubscribe, }: {
|
|
14
|
+
classNames?: RequestOrSubscribeClasses;
|
|
15
|
+
handleMagicLinkRequested?: (result: RequestMagicLinkResponse) => void;
|
|
16
|
+
handleSubscribe?: (result: SubscribeResponse) => void;
|
|
17
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useSubscriber } from '../../contexts/SubscriberProvider.js';
|
|
4
|
+
import { RequestMagicLink, Subscribe } from '../../exports/ui.js';
|
|
5
|
+
export function RequestOrSubscribe({ classNames = {
|
|
6
|
+
button: '',
|
|
7
|
+
container: '',
|
|
8
|
+
emailInput: '',
|
|
9
|
+
error: '',
|
|
10
|
+
form: '',
|
|
11
|
+
loading: '',
|
|
12
|
+
message: '',
|
|
13
|
+
section: ''
|
|
14
|
+
}, handleMagicLinkRequested, handleSubscribe }) {
|
|
15
|
+
const { subscriber } = useSubscriber();
|
|
16
|
+
// Example: Conditionally render something or pass the state to children
|
|
17
|
+
return /*#__PURE__*/ _jsx(_Fragment, {
|
|
18
|
+
children: subscriber ? /*#__PURE__*/ _jsx(Subscribe, {
|
|
19
|
+
classNames: classNames,
|
|
20
|
+
handleSubscribe: handleSubscribe
|
|
21
|
+
}) : /*#__PURE__*/ _jsx(RequestMagicLink, {
|
|
22
|
+
classNames: classNames,
|
|
23
|
+
handleMagicLinkRequested: handleMagicLinkRequested
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=RequestOrSubscribe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/app/RequestOrSubscribe.tsx"],"sourcesContent":["'use client'\n\nimport { useSubscriber } from '../../contexts/SubscriberProvider.js'\nimport {\n RequestMagicLink,\n type RequestMagicLinkResponse,\n Subscribe,\n type SubscribeResponse,\n} from '../../exports/ui.js'\n\nexport type { RequestMagicLinkResponse, SubscribeResponse }\n\nexport type RequestOrSubscribeClasses = {\n button?: string\n container?: string\n emailInput?: string\n error?: string\n form?: string\n loading?: string\n message?: string\n section?: string\n}\n\nexport function RequestOrSubscribe({\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n section: '',\n },\n handleMagicLinkRequested,\n handleSubscribe,\n}: {\n classNames?: RequestOrSubscribeClasses\n handleMagicLinkRequested?: (result: RequestMagicLinkResponse) => void\n handleSubscribe?: (result: SubscribeResponse) => void\n}) {\n const { subscriber } = useSubscriber()\n\n // Example: Conditionally render something or pass the state to children\n return (\n <>\n {subscriber ? (\n <Subscribe classNames={classNames} handleSubscribe={handleSubscribe} />\n ) : (\n <RequestMagicLink\n classNames={classNames}\n handleMagicLinkRequested={handleMagicLinkRequested}\n />\n )}\n {/* <div>subscriber = {JSON.stringify(subscriber)}</div> */}\n </>\n )\n}\n"],"names":["useSubscriber","RequestMagicLink","Subscribe","RequestOrSubscribe","classNames","button","container","emailInput","error","form","loading","message","section","handleMagicLinkRequested","handleSubscribe","subscriber"],"mappings":"AAAA;;AAEA,SAASA,aAAa,QAAQ,uCAAsC;AACpE,SACEC,gBAAgB,EAEhBC,SAAS,QAEJ,sBAAqB;AAe5B,OAAO,SAASC,mBAAmB,EACjCC,aAAa;IACXC,QAAQ;IACRC,WAAW;IACXC,YAAY;IACZC,OAAO;IACPC,MAAM;IACNC,SAAS;IACTC,SAAS;IACTC,SAAS;AACX,CAAC,EACDC,wBAAwB,EACxBC,eAAe,EAKhB;IACC,MAAM,EAAEC,UAAU,EAAE,GAAGf;IAEvB,wEAAwE;IACxE,qBACE;kBACGe,2BACC,KAACb;YAAUE,YAAYA;YAAYU,iBAAiBA;2BAEpD,KAACb;YACCG,YAAYA;YACZS,0BAA0BA;;;AAMpC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { OptInChannel } from '../../copied/payload-types.js';
|
|
2
|
+
export interface ISelectOptInChannels {
|
|
3
|
+
classNames?: SelectOptInChannelsClasses;
|
|
4
|
+
handleOptInChannelsSelected?: (result: OptInChannel[]) => void;
|
|
5
|
+
props?: any;
|
|
6
|
+
selectedOptInChannelIDs?: string[];
|
|
7
|
+
}
|
|
8
|
+
export type SelectOptInChannelsClasses = {
|
|
9
|
+
button?: string;
|
|
10
|
+
container?: string;
|
|
11
|
+
error?: string;
|
|
12
|
+
form?: string;
|
|
13
|
+
loading?: string;
|
|
14
|
+
message?: string;
|
|
15
|
+
optInCheckbox?: string;
|
|
16
|
+
optInCheckboxItem?: string;
|
|
17
|
+
optInCheckboxLabel?: string;
|
|
18
|
+
optionsGroup?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare const SelectOptInChannels: ({ classNames, handleOptInChannelsSelected, selectedOptInChannelIDs, }: ISelectOptInChannels) => import("react").JSX.Element;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { PayloadSDK } from '@payloadcms/sdk';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useServerUrl } from '../../react-hooks/useServerUrl.js';
|
|
6
|
+
import { mergeClassNames } from './helpers.js';
|
|
7
|
+
import styles from './shared.module.css';
|
|
8
|
+
export const SelectOptInChannels = ({ classNames = {
|
|
9
|
+
button: '',
|
|
10
|
+
container: '',
|
|
11
|
+
error: '',
|
|
12
|
+
form: '',
|
|
13
|
+
loading: '',
|
|
14
|
+
message: '',
|
|
15
|
+
optInCheckbox: '',
|
|
16
|
+
optInCheckboxItem: '',
|
|
17
|
+
optInCheckboxLabel: '',
|
|
18
|
+
optionsGroup: ''
|
|
19
|
+
}, handleOptInChannelsSelected, selectedOptInChannelIDs })=>{
|
|
20
|
+
const { serverURL } = useServerUrl();
|
|
21
|
+
const [result, setResult] = useState();
|
|
22
|
+
const [allOptInChannels, setAllOptInChannels] = useState([]);
|
|
23
|
+
useEffect(()=>{
|
|
24
|
+
async function verify() {
|
|
25
|
+
const sdk = new PayloadSDK({
|
|
26
|
+
baseURL: serverURL || ''
|
|
27
|
+
});
|
|
28
|
+
console.log('calling optinchannels endpoint');
|
|
29
|
+
const result = await sdk.request({
|
|
30
|
+
method: 'GET',
|
|
31
|
+
path: '/api/optinchannels'
|
|
32
|
+
});
|
|
33
|
+
if (result.ok) {
|
|
34
|
+
const resultJson = await result.json();
|
|
35
|
+
setResult(resultJson);
|
|
36
|
+
} else {
|
|
37
|
+
const resultText = await result.text();
|
|
38
|
+
setResult(resultText);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
void verify();
|
|
42
|
+
}, [
|
|
43
|
+
serverURL
|
|
44
|
+
]);
|
|
45
|
+
useEffect(()=>{
|
|
46
|
+
const channels = result?.optInChannels?.map((channel)=>({
|
|
47
|
+
...channel,
|
|
48
|
+
isChecked: selectedOptInChannelIDs?.includes(channel.id)
|
|
49
|
+
}));
|
|
50
|
+
setAllOptInChannels(channels);
|
|
51
|
+
}, [
|
|
52
|
+
result,
|
|
53
|
+
selectedOptInChannelIDs
|
|
54
|
+
]);
|
|
55
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
56
|
+
className: mergeClassNames([
|
|
57
|
+
styles.container,
|
|
58
|
+
classNames.container
|
|
59
|
+
]),
|
|
60
|
+
children: [
|
|
61
|
+
/*#__PURE__*/ _jsx("h3", {
|
|
62
|
+
children: "Opt-in Channels"
|
|
63
|
+
}),
|
|
64
|
+
!result ? /*#__PURE__*/ _jsx("p", {
|
|
65
|
+
className: mergeClassNames([
|
|
66
|
+
styles.loading,
|
|
67
|
+
classNames.loading
|
|
68
|
+
]),
|
|
69
|
+
children: "verifying..."
|
|
70
|
+
}) : /*#__PURE__*/ _jsx("div", {
|
|
71
|
+
className: mergeClassNames([
|
|
72
|
+
styles.optionsGroup,
|
|
73
|
+
classNames.optionsGroup
|
|
74
|
+
]),
|
|
75
|
+
children: allOptInChannels?.map((channel)=>/*#__PURE__*/ _jsx("div", {
|
|
76
|
+
className: mergeClassNames([
|
|
77
|
+
styles.optInCheckboxItem,
|
|
78
|
+
classNames.optInCheckboxItem
|
|
79
|
+
]),
|
|
80
|
+
children: /*#__PURE__*/ _jsxs("label", {
|
|
81
|
+
className: mergeClassNames([
|
|
82
|
+
styles.optInCheckboxLabel,
|
|
83
|
+
classNames.optInCheckboxLabel
|
|
84
|
+
]),
|
|
85
|
+
children: [
|
|
86
|
+
/*#__PURE__*/ _jsx("input", {
|
|
87
|
+
"aria-label": channel.title,
|
|
88
|
+
// The checked prop is controlled by the state
|
|
89
|
+
checked: channel.isChecked,
|
|
90
|
+
className: mergeClassNames([
|
|
91
|
+
styles.optInCheckbox,
|
|
92
|
+
classNames.optInCheckbox
|
|
93
|
+
]),
|
|
94
|
+
// The onChange handler calls the update function with the item's ID
|
|
95
|
+
onChange: (event)=>{
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
const checked = event.target.checked;
|
|
98
|
+
if (handleOptInChannelsSelected) {
|
|
99
|
+
handleOptInChannelsSelected(allOptInChannels.map((channel)=>({
|
|
100
|
+
...channel,
|
|
101
|
+
isChecked: channel.title == event.target.value ? checked : channel.isChecked
|
|
102
|
+
})).filter((c)=>c.isChecked).map((channel)=>({
|
|
103
|
+
...channel,
|
|
104
|
+
isChecked: undefined
|
|
105
|
+
})));
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
type: "checkbox",
|
|
109
|
+
value: channel.title
|
|
110
|
+
}),
|
|
111
|
+
channel.title
|
|
112
|
+
]
|
|
113
|
+
})
|
|
114
|
+
}, channel.id))
|
|
115
|
+
})
|
|
116
|
+
]
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=SelectOptInChannels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/app/SelectOptInChannels.tsx"],"sourcesContent":["'use client'\n\nimport { PayloadSDK } from '@payloadcms/sdk'\nimport { useEffect, useState } from 'react'\n\nimport type { Config, OptInChannel } from '../../copied/payload-types.js'\nimport type { GetOptInChannelsResponse } from '../../endpoints/getOptInChannels.js'\n\nimport { useServerUrl } from '../../react-hooks/useServerUrl.js'\nimport { mergeClassNames } from './helpers.js'\nimport styles from './shared.module.css'\n\n// const payload = await getPayload({\n// config: configPromise,\n// })\n\n// Pass your config from generated types as generic\n\nexport interface ISelectOptInChannels {\n classNames?: SelectOptInChannelsClasses\n handleOptInChannelsSelected?: (result: OptInChannel[]) => void\n props?: any\n selectedOptInChannelIDs?: string[]\n}\n\nexport type SelectOptInChannelsClasses = {\n button?: string\n container?: string\n error?: string\n form?: string\n loading?: string\n message?: string\n optInCheckbox?: string\n optInCheckboxItem?: string\n optInCheckboxLabel?: string\n optionsGroup?: string\n}\n\nexport const SelectOptInChannels = ({\n classNames = {\n button: '',\n container: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n optInCheckbox: '',\n optInCheckboxItem: '',\n optInCheckboxLabel: '',\n optionsGroup: '',\n },\n handleOptInChannelsSelected,\n selectedOptInChannelIDs,\n}: ISelectOptInChannels) => {\n const { serverURL } = useServerUrl()\n // const { serverURL } = { serverURL: 'http://localhost:3001' }\n type OptInChannelCheckbox = {\n isChecked: boolean\n } & OptInChannel\n const [result, setResult] = useState<any>()\n const [allOptInChannels, setAllOptInChannels] = useState<OptInChannelCheckbox[]>([])\n\n useEffect(() => {\n async function verify() {\n const sdk = new PayloadSDK<Config>({\n baseURL: serverURL || '',\n })\n\n console.log('calling optinchannels endpoint')\n const result = await sdk.request({\n method: 'GET',\n path: '/api/optinchannels',\n })\n if (result.ok) {\n const resultJson: GetOptInChannelsResponse = await result.json()\n setResult(resultJson)\n } else {\n const resultText = await result.text()\n setResult(resultText)\n }\n }\n void verify()\n }, [serverURL])\n\n useEffect(() => {\n const channels = result?.optInChannels?.map((channel: OptInChannel) => ({\n ...channel,\n isChecked: selectedOptInChannelIDs?.includes(channel.id),\n }))\n setAllOptInChannels(channels)\n }, [result, selectedOptInChannelIDs])\n\n return (\n <div className={mergeClassNames([styles.container, classNames.container])}>\n <h3>Opt-in Channels</h3>\n {!result ? (\n <p className={mergeClassNames([styles.loading, classNames.loading])}>verifying...</p>\n ) : (\n <div className={mergeClassNames([styles.optionsGroup, classNames.optionsGroup])}>\n {// Map over the tasks array to render each checkbox\n allOptInChannels?.map((channel) => (\n <div\n className={mergeClassNames([styles.optInCheckboxItem, classNames.optInCheckboxItem])}\n key={channel.id}\n >\n <label\n className={mergeClassNames([\n styles.optInCheckboxLabel,\n classNames.optInCheckboxLabel,\n ])}\n >\n <input\n aria-label={channel.title}\n // The checked prop is controlled by the state\n checked={channel.isChecked}\n className={mergeClassNames([styles.optInCheckbox, classNames.optInCheckbox])}\n // The onChange handler calls the update function with the item's ID\n onChange={(event) => {\n event.preventDefault()\n\n const checked = event.target.checked\n\n if (handleOptInChannelsSelected) {\n handleOptInChannelsSelected(\n allOptInChannels\n .map((channel) => ({\n ...channel,\n isChecked:\n channel.title == event.target.value ? checked : channel.isChecked,\n }))\n .filter((c) => c.isChecked)\n .map((channel) => ({ ...channel, isChecked: undefined })),\n )\n }\n }}\n type=\"checkbox\"\n value={channel.title}\n />\n {channel.title}\n </label>\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n"],"names":["PayloadSDK","useEffect","useState","useServerUrl","mergeClassNames","styles","SelectOptInChannels","classNames","button","container","error","form","loading","message","optInCheckbox","optInCheckboxItem","optInCheckboxLabel","optionsGroup","handleOptInChannelsSelected","selectedOptInChannelIDs","serverURL","result","setResult","allOptInChannels","setAllOptInChannels","verify","sdk","baseURL","console","log","request","method","path","ok","resultJson","json","resultText","text","channels","optInChannels","map","channel","isChecked","includes","id","div","className","h3","p","label","input","aria-label","title","checked","onChange","event","preventDefault","target","value","filter","c","undefined","type"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SubscribeResponse } from '../../endpoints/subscribe.js';
|
|
2
|
+
export { SubscribeResponse };
|
|
3
|
+
export interface ISubscribe {
|
|
4
|
+
classNames?: SubscribeClasses;
|
|
5
|
+
handleSubscribe?: (result: SubscribeResponse) => void;
|
|
6
|
+
props?: any;
|
|
7
|
+
}
|
|
8
|
+
export type SubscribeClasses = {
|
|
9
|
+
button?: string;
|
|
10
|
+
container?: string;
|
|
11
|
+
emailInput?: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
form?: string;
|
|
14
|
+
loading?: string;
|
|
15
|
+
message?: string;
|
|
16
|
+
section?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const Subscribe: ({ classNames, handleSubscribe, }: ISubscribe) => import("react").JSX.Element;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { PayloadSDK } from '@payloadcms/sdk';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useSubscriber } from '../../contexts/SubscriberProvider.js';
|
|
6
|
+
import { useServerUrl } from '../../react-hooks/useServerUrl.js';
|
|
7
|
+
import { mergeClassNames } from './helpers.js';
|
|
8
|
+
import { SelectOptInChannels } from './SelectOptInChannels.js';
|
|
9
|
+
import styles from './shared.module.css';
|
|
10
|
+
export const Subscribe = ({ classNames = {
|
|
11
|
+
button: '',
|
|
12
|
+
container: '',
|
|
13
|
+
emailInput: '',
|
|
14
|
+
error: '',
|
|
15
|
+
form: '',
|
|
16
|
+
loading: '',
|
|
17
|
+
message: '',
|
|
18
|
+
section: ''
|
|
19
|
+
}, handleSubscribe })=>{
|
|
20
|
+
const { refreshSubscriber, subscriber } = useSubscriber();
|
|
21
|
+
const { serverURL } = useServerUrl();
|
|
22
|
+
const sdk = new PayloadSDK({
|
|
23
|
+
baseURL: serverURL || ''
|
|
24
|
+
});
|
|
25
|
+
const flattenChannels = (channels)=>{
|
|
26
|
+
if (!channels) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
return channels.map((channel)=>typeof channel == 'string' ? channel : channel.id);
|
|
30
|
+
};
|
|
31
|
+
const [status, setStatus] = useState('default');
|
|
32
|
+
const [result, setResult] = useState();
|
|
33
|
+
const [email, setEmail] = useState(subscriber ? subscriber.email : '');
|
|
34
|
+
const [selectedChannelIDs, setSelectedChannelIDs] = useState(()=>flattenChannels(subscriber?.optIns));
|
|
35
|
+
useEffect(()=>{
|
|
36
|
+
setEmail(subscriber?.email || '');
|
|
37
|
+
setSelectedChannelIDs(flattenChannels(subscriber?.optIns));
|
|
38
|
+
}, [
|
|
39
|
+
subscriber
|
|
40
|
+
]);
|
|
41
|
+
const handleOptInChannelsSelected = (result)=>{
|
|
42
|
+
setSelectedChannelIDs(result.map((channel)=>channel.id));
|
|
43
|
+
};
|
|
44
|
+
const handleSubmit = async ()=>{
|
|
45
|
+
const subscribeResult = await sdk.request({
|
|
46
|
+
json: {
|
|
47
|
+
afterVerifyUrl: window.location.pathname + '?now=' + new Date().toISOString(),
|
|
48
|
+
email,
|
|
49
|
+
optIns: selectedChannelIDs
|
|
50
|
+
},
|
|
51
|
+
method: 'POST',
|
|
52
|
+
path: '/api/subscribe'
|
|
53
|
+
});
|
|
54
|
+
if (subscribeResult.ok) {
|
|
55
|
+
const resultJson = await subscribeResult.json();
|
|
56
|
+
// // When subscriber optIns are updated...
|
|
57
|
+
// | {
|
|
58
|
+
// email: string
|
|
59
|
+
// now: string
|
|
60
|
+
// optIns: string[]
|
|
61
|
+
// }
|
|
62
|
+
// // When a verify link is emailed...
|
|
63
|
+
// | {
|
|
64
|
+
// emailResult: any
|
|
65
|
+
// now: string
|
|
66
|
+
// }
|
|
67
|
+
// // When any error occurs...
|
|
68
|
+
// | {
|
|
69
|
+
// error: string
|
|
70
|
+
// now: string
|
|
71
|
+
// }
|
|
72
|
+
// @ts-expect-error Silly type confusion
|
|
73
|
+
const { emailResult, error } = resultJson;
|
|
74
|
+
if (error) {
|
|
75
|
+
setStatus('error');
|
|
76
|
+
setResult(`An error occured. Please try again. \n ${error}`);
|
|
77
|
+
} else if (emailResult) {
|
|
78
|
+
setStatus('sent');
|
|
79
|
+
setResult('An email has been sent containing your magic link.');
|
|
80
|
+
} else if (email) {
|
|
81
|
+
setStatus('updated');
|
|
82
|
+
setResult(`You're subscriptions have been updated.`);
|
|
83
|
+
} else {
|
|
84
|
+
setStatus('error');
|
|
85
|
+
setResult(`An error occured. Please try again. \nResult unknown`);
|
|
86
|
+
}
|
|
87
|
+
refreshSubscriber();
|
|
88
|
+
if (handleSubscribe) {
|
|
89
|
+
handleSubscribe(resultJson);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
// const resultText = await subscribeResult.text()
|
|
93
|
+
setStatus('error');
|
|
94
|
+
setResult(`An error occured. Please try again. \nResult unknown`);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
98
|
+
className: mergeClassNames([
|
|
99
|
+
styles.container,
|
|
100
|
+
classNames.container
|
|
101
|
+
]),
|
|
102
|
+
children: [
|
|
103
|
+
/*#__PURE__*/ _jsx("h2", {
|
|
104
|
+
children: "Subscribe"
|
|
105
|
+
}),
|
|
106
|
+
/*#__PURE__*/ _jsx("div", {
|
|
107
|
+
className: mergeClassNames([
|
|
108
|
+
styles.section,
|
|
109
|
+
classNames.section
|
|
110
|
+
]),
|
|
111
|
+
children: /*#__PURE__*/ _jsx(SelectOptInChannels, {
|
|
112
|
+
handleOptInChannelsSelected: handleOptInChannelsSelected,
|
|
113
|
+
selectedOptInChannelIDs: selectedChannelIDs
|
|
114
|
+
})
|
|
115
|
+
}),
|
|
116
|
+
/*#__PURE__*/ _jsx("form", {
|
|
117
|
+
className: mergeClassNames([
|
|
118
|
+
styles.form,
|
|
119
|
+
classNames.form
|
|
120
|
+
]),
|
|
121
|
+
method: "POST",
|
|
122
|
+
onSubmit: async (e)=>{
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
await handleSubmit();
|
|
125
|
+
},
|
|
126
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
127
|
+
className: mergeClassNames([
|
|
128
|
+
styles.section,
|
|
129
|
+
classNames.section
|
|
130
|
+
]),
|
|
131
|
+
children: [
|
|
132
|
+
!subscriber && /*#__PURE__*/ _jsx("input", {
|
|
133
|
+
"aria-label": "enter your email",
|
|
134
|
+
className: mergeClassNames([
|
|
135
|
+
styles.emailInput,
|
|
136
|
+
classNames.emailInput
|
|
137
|
+
]),
|
|
138
|
+
onChange: (e)=>setEmail(e.target.value),
|
|
139
|
+
placeholder: "enter your email",
|
|
140
|
+
type: "email",
|
|
141
|
+
value: email
|
|
142
|
+
}),
|
|
143
|
+
/*#__PURE__*/ _jsx("button", {
|
|
144
|
+
className: mergeClassNames([
|
|
145
|
+
styles.button,
|
|
146
|
+
classNames.button
|
|
147
|
+
]),
|
|
148
|
+
type: "submit",
|
|
149
|
+
children: "Save choices"
|
|
150
|
+
})
|
|
151
|
+
]
|
|
152
|
+
})
|
|
153
|
+
}),
|
|
154
|
+
!!result && /*#__PURE__*/ _jsx("p", {
|
|
155
|
+
className: mergeClassNames([
|
|
156
|
+
styles.message,
|
|
157
|
+
classNames.message,
|
|
158
|
+
status == 'error' ? [
|
|
159
|
+
styles.error,
|
|
160
|
+
classNames.error
|
|
161
|
+
] : []
|
|
162
|
+
]),
|
|
163
|
+
children: result
|
|
164
|
+
})
|
|
165
|
+
]
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
//# sourceMappingURL=Subscribe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/app/Subscribe.tsx"],"sourcesContent":["'use client'\n\nimport { PayloadSDK } from '@payloadcms/sdk'\nimport { type ChangeEvent, useEffect, useState } from 'react'\n\nimport type { Config, OptInChannel } from '../../copied/payload-types.js'\nimport type { SubscribeResponse } from '../../endpoints/subscribe.js'\n\nexport { SubscribeResponse }\n\nimport { useSubscriber } from '../../contexts/SubscriberProvider.js'\nimport { useServerUrl } from '../../react-hooks/useServerUrl.js'\nimport { mergeClassNames } from './helpers.js'\nimport { SelectOptInChannels } from './SelectOptInChannels.js'\nimport styles from './shared.module.css'\n\n// const payload = await getPayload({\n// config: configPromise,\n// })\n\n// Pass your config from generated types as generic\n\nexport interface ISubscribe {\n classNames?: SubscribeClasses\n handleSubscribe?: (result: SubscribeResponse) => void\n props?: any\n}\n\nexport type SubscribeClasses = {\n button?: string\n container?: string\n emailInput?: string\n error?: string\n form?: string\n loading?: string\n message?: string\n section?: string\n}\n\ntype statusValues = 'default' | 'error' | 'sent' | 'updated'\n\nexport const Subscribe = ({\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n section: '',\n },\n handleSubscribe,\n}: ISubscribe) => {\n const { refreshSubscriber, subscriber } = useSubscriber()\n\n const { serverURL } = useServerUrl()\n\n const sdk = new PayloadSDK<Config>({\n baseURL: serverURL || '',\n })\n\n const flattenChannels = (channels: (OptInChannel | string)[] | null | undefined) => {\n if (!channels) {\n return []\n }\n return channels.map((channel: OptInChannel | string) =>\n typeof channel == 'string' ? channel : channel.id,\n )\n }\n\n const [status, setStatus] = useState<statusValues>('default')\n const [result, setResult] = useState<string>()\n const [email, setEmail] = useState(subscriber ? subscriber.email : '')\n const [selectedChannelIDs, setSelectedChannelIDs] = useState<string[]>(() =>\n flattenChannels(subscriber?.optIns),\n )\n\n useEffect(() => {\n setEmail(subscriber?.email || '')\n setSelectedChannelIDs(flattenChannels(subscriber?.optIns))\n }, [subscriber])\n\n const handleOptInChannelsSelected = (result: OptInChannel[]) => {\n setSelectedChannelIDs(result.map((channel) => channel.id))\n }\n\n const handleSubmit = async () => {\n const subscribeResult = await sdk.request({\n json: {\n afterVerifyUrl: window.location.pathname + '?now=' + new Date().toISOString(),\n email,\n optIns: selectedChannelIDs,\n },\n method: 'POST',\n path: '/api/subscribe',\n })\n if (subscribeResult.ok) {\n const resultJson: SubscribeResponse = await subscribeResult.json()\n // // When subscriber optIns are updated...\n // | {\n // email: string\n // now: string\n // optIns: string[]\n // }\n // // When a verify link is emailed...\n // | {\n // emailResult: any\n // now: string\n // }\n // // When any error occurs...\n // | {\n // error: string\n // now: string\n // }\n // @ts-expect-error Silly type confusion\n const { emailResult, error } = resultJson\n if (error) {\n setStatus('error')\n setResult(`An error occured. Please try again. \\n ${error}`)\n } else if (emailResult) {\n setStatus('sent')\n setResult('An email has been sent containing your magic link.')\n } else if (email) {\n setStatus('updated')\n setResult(`You're subscriptions have been updated.`)\n } else {\n setStatus('error')\n setResult(`An error occured. Please try again. \\nResult unknown`)\n }\n\n refreshSubscriber()\n\n if (handleSubscribe) {\n handleSubscribe(resultJson)\n }\n } else {\n // const resultText = await subscribeResult.text()\n setStatus('error')\n setResult(`An error occured. Please try again. \\nResult unknown`)\n }\n }\n\n return (\n <div className={mergeClassNames([styles.container, classNames.container])}>\n <h2>Subscribe</h2>\n <div className={mergeClassNames([styles.section, classNames.section])}>\n <SelectOptInChannels\n handleOptInChannelsSelected={handleOptInChannelsSelected}\n selectedOptInChannelIDs={selectedChannelIDs}\n />\n </div>\n <form\n className={mergeClassNames([styles.form, classNames.form])}\n method=\"POST\"\n onSubmit={async (e) => {\n e.preventDefault()\n await handleSubmit()\n }}\n >\n <div className={mergeClassNames([styles.section, classNames.section])}>\n {!subscriber && (\n <input\n aria-label=\"enter your email\"\n className={mergeClassNames([styles.emailInput, classNames.emailInput])}\n onChange={(e: ChangeEvent<HTMLInputElement>) => setEmail(e.target.value)}\n placeholder=\"enter your email\"\n type=\"email\"\n value={email}\n />\n )}\n <button className={mergeClassNames([styles.button, classNames.button])} type=\"submit\">\n Save choices\n </button>\n </div>\n </form>\n {!!result && (\n <p\n className={mergeClassNames([\n styles.message,\n classNames.message,\n status == 'error' ? [styles.error, classNames.error] : [],\n ])}\n >\n {result}\n </p>\n )}\n </div>\n )\n}\n"],"names":["PayloadSDK","useEffect","useState","useSubscriber","useServerUrl","mergeClassNames","SelectOptInChannels","styles","Subscribe","classNames","button","container","emailInput","error","form","loading","message","section","handleSubscribe","refreshSubscriber","subscriber","serverURL","sdk","baseURL","flattenChannels","channels","map","channel","id","status","setStatus","result","setResult","email","setEmail","selectedChannelIDs","setSelectedChannelIDs","optIns","handleOptInChannelsSelected","handleSubmit","subscribeResult","request","json","afterVerifyUrl","window","location","pathname","Date","toISOString","method","path","ok","resultJson","emailResult","div","className","h2","selectedOptInChannelIDs","onSubmit","e","preventDefault","input","aria-label","onChange","target","value","placeholder","type","p"],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useSubscriber } from '../../contexts/SubscriberProvider.js';
|
|
4
|
+
import { mergeClassNames } from './helpers.js';
|
|
5
|
+
import styles from './shared.module.css';
|
|
6
|
+
export const SubscriberMenu = ({ classNames = {
|
|
7
|
+
button: '',
|
|
8
|
+
container: ''
|
|
9
|
+
} })=>{
|
|
10
|
+
const { logOut, subscriber } = useSubscriber();
|
|
11
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
12
|
+
className: mergeClassNames([
|
|
13
|
+
styles.container,
|
|
14
|
+
classNames.container
|
|
15
|
+
]),
|
|
16
|
+
children: subscriber && /*#__PURE__*/ _jsxs("div", {
|
|
17
|
+
children: [
|
|
18
|
+
"Welcome, ",
|
|
19
|
+
subscriber?.email,
|
|
20
|
+
" - ",
|
|
21
|
+
/*#__PURE__*/ _jsx("a", {
|
|
22
|
+
href: '/subscribe',
|
|
23
|
+
children: "Manage subscriptions"
|
|
24
|
+
}),
|
|
25
|
+
" -",
|
|
26
|
+
' ',
|
|
27
|
+
/*#__PURE__*/ _jsx("button", {
|
|
28
|
+
className: mergeClassNames([
|
|
29
|
+
styles.button,
|
|
30
|
+
classNames.button
|
|
31
|
+
]),
|
|
32
|
+
onClick: (e)=>{
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
logOut();
|
|
35
|
+
},
|
|
36
|
+
type: "button",
|
|
37
|
+
children: "Log out"
|
|
38
|
+
})
|
|
39
|
+
]
|
|
40
|
+
})
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=SubscriberMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/app/SubscriberMenu.tsx"],"sourcesContent":["'use client'\n\nimport { useSubscriber } from '../../contexts/SubscriberProvider.js'\n\nimport { mergeClassNames } from './helpers.js'\nimport styles from './shared.module.css'\n\n// interface IAuth {\n// props?: any\n// }\n\nexport type SubscriberMenuClasses = {\n button?: string\n container?: string\n}\n\nexport const SubscriberMenu = ({\n classNames = {\n button: '',\n container: '',\n },\n}: {\n classNames?: SubscriberMenuClasses\n}) => {\n const { logOut, subscriber } = useSubscriber()\n return (\n <div className={mergeClassNames([styles.container, classNames.container])}>\n {/* <pre>{JSON.stringify(result, null, 2)}</pre> */}\n {subscriber && (\n <div>\n Welcome, {subscriber?.email} - <a href={'/subscribe'}>Manage subscriptions</a> -{' '}\n <button\n className={mergeClassNames([styles.button, classNames.button])}\n onClick={(e) => {\n e.preventDefault()\n logOut()\n }}\n type=\"button\"\n >\n Log out\n </button>\n </div>\n )}\n </div>\n )\n}\n"],"names":["useSubscriber","mergeClassNames","styles","SubscriberMenu","classNames","button","container","logOut","subscriber","div","className","email","a","href","onClick","e","preventDefault","type"],"mappings":"AAAA;;AAEA,SAASA,aAAa,QAAQ,uCAAsC;AAEpE,SAASC,eAAe,QAAQ,eAAc;AAC9C,OAAOC,YAAY,sBAAqB;AAWxC,OAAO,MAAMC,iBAAiB,CAAC,EAC7BC,aAAa;IACXC,QAAQ;IACRC,WAAW;AACb,CAAC,EAGF;IACC,MAAM,EAAEC,MAAM,EAAEC,UAAU,EAAE,GAAGR;IAC/B,qBACE,KAACS;QAAIC,WAAWT,gBAAgB;YAACC,OAAOI,SAAS;YAAEF,WAAWE,SAAS;SAAC;kBAErEE,4BACC,MAACC;;gBAAI;gBACOD,YAAYG;gBAAM;8BAAG,KAACC;oBAAEC,MAAM;8BAAc;;gBAAwB;gBAAG;8BACjF,KAACR;oBACCK,WAAWT,gBAAgB;wBAACC,OAAOG,MAAM;wBAAED,WAAWC,MAAM;qBAAC;oBAC7DS,SAAS,CAACC;wBACRA,EAAEC,cAAc;wBAChBT;oBACF;oBACAU,MAAK;8BACN;;;;;AAOX,EAAC"}
|