@scalemule/news-publication 0.0.48 → 0.0.49

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.
Files changed (72) hide show
  1. package/README.md +28 -0
  2. package/dist/{chunk-GB36YM56.js → chunk-2MEYHM7M.js} +11 -1
  3. package/dist/chunk-4JRWZXAP.js +62 -0
  4. package/dist/chunk-MBBPEFDA.js +124 -0
  5. package/dist/chunk-TTLM7YOH.js +444 -0
  6. package/dist/chunk-ZXH3O537.js +251 -0
  7. package/dist/community-maps-view.d.cts +3 -3
  8. package/dist/community-maps-view.d.ts +3 -3
  9. package/dist/cookie-consent-banner.d.cts +2 -2
  10. package/dist/cookie-consent-banner.d.ts +2 -2
  11. package/dist/cookie-settings-view.d.cts +2 -2
  12. package/dist/cookie-settings-view.d.ts +2 -2
  13. package/dist/index.cjs +29 -1
  14. package/dist/index.d.cts +4 -3
  15. package/dist/index.d.ts +4 -3
  16. package/dist/index.js +4 -3
  17. package/dist/marketplace-forms.d.cts +3 -3
  18. package/dist/marketplace-forms.d.ts +3 -3
  19. package/dist/marketplace-view.d.cts +5 -5
  20. package/dist/marketplace-view.d.ts +5 -5
  21. package/dist/{meet-RWmfj3I3.d.cts → meet-BWpxY20X.d.ts} +5 -0
  22. package/dist/{meet-RWmfj3I3.d.ts → meet-CO9Unz5M.d.cts} +5 -0
  23. package/dist/meet-forms.d.cts +7 -6
  24. package/dist/meet-forms.d.ts +7 -6
  25. package/dist/meet-forms.js +2 -1
  26. package/dist/meet-view.cjs +22 -2
  27. package/dist/meet-view.d.cts +7 -5
  28. package/dist/meet-view.d.ts +7 -5
  29. package/dist/meet-view.js +21 -4
  30. package/dist/network-bar.d.cts +2 -2
  31. package/dist/network-bar.d.ts +2 -2
  32. package/dist/network-copyright.d.cts +2 -2
  33. package/dist/network-copyright.d.ts +2 -2
  34. package/dist/pets-auth-server.cjs +212 -0
  35. package/dist/pets-auth-server.d.cts +17 -0
  36. package/dist/pets-auth-server.d.ts +17 -0
  37. package/dist/pets-auth-server.js +155 -0
  38. package/dist/pets-forms.cjs +762 -0
  39. package/dist/pets-forms.d.cts +26 -0
  40. package/dist/pets-forms.d.ts +26 -0
  41. package/dist/pets-forms.js +712 -0
  42. package/dist/pets-interactions.cjs +332 -0
  43. package/dist/pets-interactions.d.cts +20 -0
  44. package/dist/pets-interactions.d.ts +20 -0
  45. package/dist/pets-interactions.js +319 -0
  46. package/dist/pets-publication.cjs +818 -0
  47. package/dist/pets-publication.d.cts +36 -0
  48. package/dist/pets-publication.d.ts +36 -0
  49. package/dist/pets-publication.js +177 -0
  50. package/dist/pets-server.cjs +289 -0
  51. package/dist/pets-server.d.cts +42 -0
  52. package/dist/pets-server.d.ts +42 -0
  53. package/dist/pets-server.js +2 -0
  54. package/dist/pets-view.cjs +541 -0
  55. package/dist/pets-view.d.cts +56 -0
  56. package/dist/pets-view.d.ts +56 -0
  57. package/dist/pets-view.js +4 -0
  58. package/dist/pets.cjs +138 -0
  59. package/dist/pets.d.cts +127 -0
  60. package/dist/pets.d.ts +127 -0
  61. package/dist/pets.js +1 -0
  62. package/dist/sponsorship-view.d.cts +2 -2
  63. package/dist/sponsorship-view.d.ts +2 -2
  64. package/dist/sponsorship-view.js +2 -62
  65. package/dist/story-review.d.cts +6 -6
  66. package/dist/story-review.d.ts +6 -6
  67. package/dist/theme-toggle.d.cts +2 -2
  68. package/dist/theme-toggle.d.ts +2 -2
  69. package/dist/verified-card.d.cts +3 -3
  70. package/dist/verified-card.d.ts +3 -3
  71. package/package.json +40 -3
  72. package/pets.css +538 -0
@@ -0,0 +1,319 @@
1
+ "use client";
2
+ import { PET_NOTIFICATION_CATEGORIES } from './chunk-MBBPEFDA.js';
3
+ import { useState, useEffect, useRef } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ async function request(path, method = "GET", body) {
7
+ const response = await fetch(path, {
8
+ method,
9
+ credentials: "same-origin",
10
+ headers: { "content-type": "application/json" },
11
+ body: body === void 0 ? void 0 : JSON.stringify(body)
12
+ });
13
+ const value = await response.json();
14
+ if (!response.ok)
15
+ throw new Error(
16
+ typeof value.error === "string" ? value.error : "Please try again."
17
+ );
18
+ return value.data ?? value;
19
+ }
20
+ function PetSignOut() {
21
+ const [error, setError] = useState("");
22
+ return /* @__PURE__ */ jsxs("div", { children: [
23
+ /* @__PURE__ */ jsx(
24
+ "button",
25
+ {
26
+ onClick: async () => {
27
+ try {
28
+ await request("/api/paw-auth/logout", "POST");
29
+ window.location.assign("/");
30
+ } catch {
31
+ setError("Sign-out could not be completed. Please try again.");
32
+ }
33
+ },
34
+ children: "Sign out"
35
+ }
36
+ ),
37
+ error && /* @__PURE__ */ jsx("p", { role: "alert", children: error })
38
+ ] });
39
+ }
40
+ function PetCommunityMemory({
41
+ selected,
42
+ signedIn
43
+ }) {
44
+ const [error, setError] = useState("");
45
+ useEffect(() => {
46
+ if (selected === void 0) return;
47
+ void request("/api/paw-community", "POST", { area_id: selected }).catch(
48
+ () => setError("Your community could not be remembered on this device.")
49
+ );
50
+ if (signedIn)
51
+ void request("/api/pets/preferences").then((record) => {
52
+ if (record.preferences.home_area_id === selected) return;
53
+ return request("/api/pets/preferences", "PUT", {
54
+ expected_revision: record.revision,
55
+ preferences: { ...record.preferences, home_area_id: selected }
56
+ });
57
+ }).catch(
58
+ () => setError(
59
+ "Your account preference could not be saved. You can retry from My pets."
60
+ )
61
+ );
62
+ }, [selected, signedIn]);
63
+ return error ? /* @__PURE__ */ jsx("p", { className: "paw-safety", role: "status", children: error }) : null;
64
+ }
65
+ function PetPreferencesForm({
66
+ record,
67
+ communities,
68
+ notificationsReady = false
69
+ }) {
70
+ const [value, setValue] = useState(record.preferences), [revision, setRevision] = useState(record.revision), [message, setMessage] = useState(""), [busy, setBusy] = useState(false);
71
+ return /* @__PURE__ */ jsxs(
72
+ "form",
73
+ {
74
+ className: "paw-form",
75
+ onSubmit: async (event) => {
76
+ event.preventDefault();
77
+ setBusy(true);
78
+ setMessage("");
79
+ try {
80
+ const result = await request(
81
+ "/api/pets/preferences",
82
+ "PUT",
83
+ { expected_revision: revision, preferences: value }
84
+ );
85
+ setRevision(result.revision);
86
+ setValue(result.preferences);
87
+ setMessage("Your preferences are saved.");
88
+ await request("/api/paw-community", "POST", {
89
+ area_id: value.home_area_id
90
+ });
91
+ } catch (error) {
92
+ setMessage(
93
+ error instanceof Error ? error.message : "Please try again."
94
+ );
95
+ } finally {
96
+ setBusy(false);
97
+ }
98
+ },
99
+ children: [
100
+ /* @__PURE__ */ jsx("h2", { children: "Your community, your pace." }),
101
+ /* @__PURE__ */ jsxs("label", { children: [
102
+ "Home community",
103
+ /* @__PURE__ */ jsxs(
104
+ "select",
105
+ {
106
+ value: value.home_area_id || "",
107
+ onChange: (e) => setValue({ ...value, home_area_id: e.target.value || null }),
108
+ children: [
109
+ /* @__PURE__ */ jsx("option", { value: "", children: "The whole Bay Area" }),
110
+ communities.map((c) => /* @__PURE__ */ jsx("option", { value: c.id, children: c.name }, c.id))
111
+ ]
112
+ }
113
+ )
114
+ ] }),
115
+ /* @__PURE__ */ jsxs("fieldset", { children: [
116
+ /* @__PURE__ */ jsx("legend", { children: "Communities you follow" }),
117
+ communities.map((c) => /* @__PURE__ */ jsxs("label", { className: "paw-consent", children: [
118
+ /* @__PURE__ */ jsx(
119
+ "input",
120
+ {
121
+ type: "checkbox",
122
+ checked: value.followed_area_ids.includes(c.id),
123
+ onChange: (e) => setValue({
124
+ ...value,
125
+ followed_area_ids: e.target.checked ? [...value.followed_area_ids, c.id] : value.followed_area_ids.filter((id) => id !== c.id)
126
+ })
127
+ }
128
+ ),
129
+ c.name
130
+ ] }, c.id))
131
+ ] }),
132
+ /* @__PURE__ */ jsxs("fieldset", { disabled: !notificationsReady, children: [
133
+ /* @__PURE__ */ jsx("legend", { children: "Optional community updates" }),
134
+ !notificationsReady && /* @__PURE__ */ jsx("p", { children: "Community alerts are not active yet. No emails or alerts will be sent from these settings." }),
135
+ PET_NOTIFICATION_CATEGORIES.map(([key, label]) => /* @__PURE__ */ jsxs("label", { className: "paw-consent", children: [
136
+ /* @__PURE__ */ jsx(
137
+ "input",
138
+ {
139
+ type: "checkbox",
140
+ checked: value.categories.includes(key),
141
+ onChange: (e) => setValue({
142
+ ...value,
143
+ categories: e.target.checked ? [...value.categories, key] : value.categories.filter((c) => c !== key)
144
+ })
145
+ }
146
+ ),
147
+ label
148
+ ] }, key)),
149
+ /* @__PURE__ */ jsxs("label", { className: "paw-consent", children: [
150
+ /* @__PURE__ */ jsx(
151
+ "input",
152
+ {
153
+ type: "checkbox",
154
+ checked: value.email_enabled,
155
+ onChange: (e) => setValue({ ...value, email_enabled: e.target.checked })
156
+ }
157
+ ),
158
+ "Email me selected updates"
159
+ ] }),
160
+ /* @__PURE__ */ jsxs("label", { children: [
161
+ "Frequency",
162
+ /* @__PURE__ */ jsxs(
163
+ "select",
164
+ {
165
+ value: value.frequency || "weekly",
166
+ onChange: (e) => setValue({
167
+ ...value,
168
+ frequency: e.target.value
169
+ }),
170
+ children: [
171
+ /* @__PURE__ */ jsx("option", { value: "weekly", children: "Weekly digest" }),
172
+ /* @__PURE__ */ jsx("option", { value: "daily", children: "Daily digest" }),
173
+ /* @__PURE__ */ jsx("option", { value: "immediate", children: "As updates are approved" })
174
+ ]
175
+ }
176
+ )
177
+ ] })
178
+ ] }),
179
+ /* @__PURE__ */ jsx("p", { className: "paw-safety", children: "Account and submission messages are separate from optional community updates. Sponsors never receive your profile or preferences." }),
180
+ /* @__PURE__ */ jsx("button", { disabled: busy, children: "Save preferences" }),
181
+ message && /* @__PURE__ */ jsx("p", { role: "status", children: message })
182
+ ]
183
+ }
184
+ );
185
+ }
186
+ function PetResourceActions({
187
+ resource,
188
+ signedIn,
189
+ apiPath = "/api/pets"
190
+ }) {
191
+ const [active, setActive] = useState(false), [reporting, setReporting] = useState(false), [message, setMessage] = useState(""), [busy, setBusy] = useState(false);
192
+ const reportKey = useRef("");
193
+ const celebrate = ["profile", "photo", "spotlight", "celebration"].includes(resource.kind) && resource.content.category !== "memorial";
194
+ useEffect(() => {
195
+ if (signedIn && celebrate)
196
+ void request(`${apiPath}/${resource.id}/reaction`).then((v) => setActive(v.active)).catch(() => setMessage("Your reaction could not be loaded."));
197
+ }, [signedIn, celebrate, resource.id, apiPath]);
198
+ return /* @__PURE__ */ jsxs("section", { "aria-label": "Share and community care", children: [
199
+ /* @__PURE__ */ jsxs("div", { className: "paw-form-actions", children: [
200
+ /* @__PURE__ */ jsx(
201
+ "button",
202
+ {
203
+ onClick: async () => {
204
+ try {
205
+ if (navigator.share)
206
+ await navigator.share({
207
+ title: resource.content.name,
208
+ url: window.location.href
209
+ });
210
+ else {
211
+ await navigator.clipboard.writeText(window.location.href);
212
+ setMessage("Link copied.");
213
+ }
214
+ } catch (error) {
215
+ if (!(error instanceof DOMException && error.name === "AbortError"))
216
+ setMessage(
217
+ "You can copy the page address to share this story."
218
+ );
219
+ }
220
+ },
221
+ children: "Share this story"
222
+ }
223
+ ),
224
+ celebrate && signedIn && /* @__PURE__ */ jsx(
225
+ "button",
226
+ {
227
+ disabled: busy,
228
+ "aria-pressed": active,
229
+ onClick: async () => {
230
+ setBusy(true);
231
+ try {
232
+ const result = await request(
233
+ `${apiPath}/${resource.id}/reaction`,
234
+ "PUT",
235
+ { active: !active }
236
+ );
237
+ setActive(result.active);
238
+ setMessage(
239
+ result.active ? "A little love, shared." : "Reaction removed."
240
+ );
241
+ } catch (e) {
242
+ setMessage(
243
+ e instanceof Error ? e.message : "Please try again."
244
+ );
245
+ } finally {
246
+ setBusy(false);
247
+ }
248
+ },
249
+ children: active ? "Loved" : "Send a little love"
250
+ }
251
+ ),
252
+ /* @__PURE__ */ jsx(
253
+ "button",
254
+ {
255
+ "aria-expanded": reporting,
256
+ onClick: () => setReporting(!reporting),
257
+ children: "Report a concern"
258
+ }
259
+ )
260
+ ] }),
261
+ reporting && (signedIn ? /* @__PURE__ */ jsxs(
262
+ "form",
263
+ {
264
+ className: "paw-form",
265
+ onSubmit: async (event) => {
266
+ event.preventDefault();
267
+ const data = new FormData(event.currentTarget);
268
+ setBusy(true);
269
+ try {
270
+ if (!reportKey.current) reportKey.current = crypto.randomUUID();
271
+ await request(`${apiPath}/${resource.id}/reports`, "POST", {
272
+ reason: data.get("reason"),
273
+ details: data.get("details"),
274
+ idempotency_key: reportKey.current
275
+ });
276
+ setReporting(false);
277
+ setMessage(
278
+ "Your private report has been sent to the editorial team."
279
+ );
280
+ } catch (error) {
281
+ setMessage(
282
+ error instanceof Error ? error.message : "Please try again."
283
+ );
284
+ } finally {
285
+ setBusy(false);
286
+ }
287
+ },
288
+ children: [
289
+ /* @__PURE__ */ jsxs("label", { children: [
290
+ "Concern",
291
+ /* @__PURE__ */ jsxs("select", { name: "reason", children: [
292
+ /* @__PURE__ */ jsx("option", { value: "safety", children: "Safety or recovery scam" }),
293
+ /* @__PURE__ */ jsx("option", { value: "privacy-removal", children: "Privacy or removal request" }),
294
+ /* @__PURE__ */ jsx("option", { value: "inappropriate-media", children: "Inappropriate photograph" }),
295
+ /* @__PURE__ */ jsx("option", { value: "duplicate", children: "Duplicate notice" }),
296
+ /* @__PURE__ */ jsx("option", { value: "incorrect-information", children: "Incorrect information" }),
297
+ /* @__PURE__ */ jsx("option", { value: "other", children: "Something else" })
298
+ ] })
299
+ ] }),
300
+ /* @__PURE__ */ jsxs("label", { children: [
301
+ "Tell our editors",
302
+ /* @__PURE__ */ jsx("textarea", { name: "details", required: true, maxLength: 2e3 })
303
+ ] }),
304
+ /* @__PURE__ */ jsx("p", { children: "Only the editorial team can read this report. Keep contact details and ownership evidence out of it." }),
305
+ /* @__PURE__ */ jsx("button", { disabled: busy, children: "Send private report" })
306
+ ]
307
+ }
308
+ ) : /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(
309
+ "a",
310
+ {
311
+ href: "/account?next=" + encodeURIComponent(`/pets/${resource.id}`),
312
+ children: "Sign in to send a private report."
313
+ }
314
+ ) })),
315
+ message && /* @__PURE__ */ jsx("p", { role: "status", children: message })
316
+ ] });
317
+ }
318
+
319
+ export { PetCommunityMemory, PetPreferencesForm, PetResourceActions, PetSignOut };