@scalemule/news-publication 0.0.26 → 0.0.27
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 +7 -0
- package/dist/story-review.cjs +627 -447
- package/dist/story-review.d.cts +2 -1
- package/dist/story-review.d.ts +2 -1
- package/dist/story-review.js +628 -448
- package/package.json +5 -1
- package/story-review.css +330 -33
package/dist/story-review.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
2
|
+
import { useState, useRef, useEffect } from 'react';
|
|
3
3
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
// src/story-diff.ts
|
|
@@ -63,11 +63,25 @@ function EditorialNotices({ editorial }) {
|
|
|
63
63
|
var human = (s) => s.toLowerCase().replaceAll("_", " ");
|
|
64
64
|
function StoryReview({
|
|
65
65
|
sessionId,
|
|
66
|
-
publicationName
|
|
66
|
+
publicationName,
|
|
67
|
+
nameplateUrl
|
|
67
68
|
}) {
|
|
68
69
|
const base = `/api/news/review/${encodeURIComponent(sessionId)}`;
|
|
69
70
|
const [review, setReview] = useState(null), [error, setError] = useState(""), [notice, setNotice] = useState(""), [busy, setBusy] = useState(false), [panel, setPanel] = useState("article"), [verification, setVerification] = useState(false), [code, setCode] = useState("");
|
|
70
71
|
const [message, setMessage] = useState(""), [document, setDocument] = useState(null), [answers, setAnswers] = useState({}), [file, setFile] = useState(null), [rights, setRights] = useState(false), [compare, setCompare] = useState(""), [compareTo, setCompareTo] = useState(""), [editingMedia, setEditingMedia] = useState(""), [commentTarget, setCommentTarget] = useState("STORY");
|
|
72
|
+
const responseRef = useRef(null);
|
|
73
|
+
const thanksRef = useRef(null);
|
|
74
|
+
const [moreQuestions, setMoreQuestions] = useState(false);
|
|
75
|
+
const [correctionKind, setCorrectionKind] = useState("Correct a detail");
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (panel !== "article") {
|
|
78
|
+
responseRef.current?.scrollIntoView({
|
|
79
|
+
block: "start",
|
|
80
|
+
behavior: window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth"
|
|
81
|
+
});
|
|
82
|
+
responseRef.current?.focus({ preventScroll: true });
|
|
83
|
+
}
|
|
84
|
+
}, [panel]);
|
|
71
85
|
const [mediaInfo, setMediaInfo] = useState({
|
|
72
86
|
caption: "",
|
|
73
87
|
who_is_pictured: "",
|
|
@@ -153,6 +167,21 @@ function StoryReview({
|
|
|
153
167
|
}
|
|
154
168
|
}
|
|
155
169
|
const can = (p) => review?.permissions.includes(p);
|
|
170
|
+
const celebration = !!review?.celebration_type;
|
|
171
|
+
const approved = review?.decision === "APPROVED";
|
|
172
|
+
const finalEditor = review?.review_policy === "SUBJECT_APPROVAL_PLUS_EDITOR";
|
|
173
|
+
const approvalThanks = `Thank you. We're glad to help commemorate this special occasion. This version has been sent to the ${review?.publication.name || publicationName} newsroom for final editorial review. It has not been published yet.`;
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
if (approved && finalEditor && thanksRef.current) {
|
|
176
|
+
thanksRef.current.scrollIntoView({ block: "start" });
|
|
177
|
+
thanksRef.current.focus({ preventScroll: true });
|
|
178
|
+
}
|
|
179
|
+
}, [approved, finalEditor]);
|
|
180
|
+
const approve = () => {
|
|
181
|
+
if (celebration && finalEditor && !review?.questions.some((q) => q.required))
|
|
182
|
+
void send({ action: "APPROVE", message: null }, approvalThanks);
|
|
183
|
+
else setPanel("approve");
|
|
184
|
+
};
|
|
156
185
|
async function upload() {
|
|
157
186
|
if (!review || !file || !rights) return;
|
|
158
187
|
setBusy(true);
|
|
@@ -185,486 +214,637 @@ function StoryReview({
|
|
|
185
214
|
const selected = revisions.find((r) => r.id === compare), selectedAfter = revisions.find(
|
|
186
215
|
(r) => r.id === (compareTo || review?.revision.id)
|
|
187
216
|
);
|
|
188
|
-
return /* @__PURE__ */ jsxs(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
verification && /* @__PURE__ */ jsxs("section", { className: "sm-review-form", children: [
|
|
197
|
-
/* @__PURE__ */ jsx("h2", { children: "Verify your email" }),
|
|
198
|
-
/* @__PURE__ */ jsx("p", { children: "The editor requires verification using the email address on your invitation. Your story remains private until verified." }),
|
|
199
|
-
/* @__PURE__ */ jsx(
|
|
200
|
-
"button",
|
|
201
|
-
{
|
|
202
|
-
disabled: busy,
|
|
203
|
-
onClick: async () => {
|
|
204
|
-
setBusy(true);
|
|
205
|
-
setError("");
|
|
206
|
-
try {
|
|
207
|
-
await request("/verify", {});
|
|
208
|
-
setNotice(
|
|
209
|
-
"A code was sent to the email address chosen by the editor. It expires in ten minutes."
|
|
210
|
-
);
|
|
211
|
-
} catch (e) {
|
|
212
|
-
setError(
|
|
213
|
-
e instanceof Error ? e.message : "Could not send code."
|
|
214
|
-
);
|
|
215
|
-
} finally {
|
|
216
|
-
setBusy(false);
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
children: "Email me a verification code"
|
|
220
|
-
}
|
|
221
|
-
),
|
|
222
|
-
/* @__PURE__ */ jsxs(
|
|
223
|
-
"form",
|
|
224
|
-
{
|
|
225
|
-
onSubmit: async (e) => {
|
|
226
|
-
e.preventDefault();
|
|
227
|
-
setBusy(true);
|
|
228
|
-
setError("");
|
|
229
|
-
try {
|
|
230
|
-
await request("/verify", { code });
|
|
231
|
-
await load();
|
|
232
|
-
setCode("");
|
|
233
|
-
setNotice("Email verified.");
|
|
234
|
-
} catch (e2) {
|
|
235
|
-
setError(
|
|
236
|
-
e2 instanceof Error ? e2.message : "Verification failed."
|
|
237
|
-
);
|
|
238
|
-
} finally {
|
|
239
|
-
setBusy(false);
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
children: [
|
|
243
|
-
/* @__PURE__ */ jsxs("label", { children: [
|
|
244
|
-
"Eight-digit code",
|
|
245
|
-
/* @__PURE__ */ jsx(
|
|
246
|
-
"input",
|
|
247
|
-
{
|
|
248
|
-
inputMode: "numeric",
|
|
249
|
-
autoComplete: "one-time-code",
|
|
250
|
-
pattern: "[0-9]{8}",
|
|
251
|
-
required: true,
|
|
252
|
-
value: code,
|
|
253
|
-
onChange: (e) => setCode(e.target.value)
|
|
254
|
-
}
|
|
255
|
-
)
|
|
256
|
-
] }),
|
|
257
|
-
/* @__PURE__ */ jsx("button", { disabled: busy, children: "Verify and open preview" })
|
|
258
|
-
]
|
|
259
|
-
}
|
|
260
|
-
)
|
|
261
|
-
] }),
|
|
262
|
-
!review && !error && !verification && /* @__PURE__ */ jsx("p", { role: "status", children: "Opening your private preview\u2026" }),
|
|
263
|
-
review && document && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
264
|
-
/* @__PURE__ */ jsxs("div", { className: "sm-review-intro", children: [
|
|
265
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
266
|
-
"Prepared for ",
|
|
267
|
-
review.reviewer,
|
|
268
|
-
" \xB7 Version ",
|
|
269
|
-
review.revision.number
|
|
270
|
-
] }),
|
|
271
|
-
/* @__PURE__ */ jsx("p", { children: ["FACT_CHECK", "CONTRIBUTOR_REVIEW"].includes(
|
|
272
|
-
review.review_policy
|
|
273
|
-
) ? "Please help us check the facts and represent your contribution accurately. The newsroom retains the final editorial decision." : "This voluntary announcement requires subject approval before publication. You may request changes or decline participation." })
|
|
274
|
-
] }),
|
|
275
|
-
/* @__PURE__ */ jsxs("article", { className: "sm-review-article", children: [
|
|
276
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
277
|
-
review.revision.document.section,
|
|
278
|
-
review.revision.document.community && ` \xB7 ${review.revision.document.community}`
|
|
217
|
+
return /* @__PURE__ */ jsxs(
|
|
218
|
+
"main",
|
|
219
|
+
{
|
|
220
|
+
className: `sm-story-review${celebration ? " sm-review-celebration" : ""}`,
|
|
221
|
+
children: [
|
|
222
|
+
/* @__PURE__ */ jsxs("div", { className: "sm-review-private", children: [
|
|
223
|
+
/* @__PURE__ */ jsx("strong", { children: review?.published ? "Private review" : "Private preview \xB7 Not published" }),
|
|
224
|
+
/* @__PURE__ */ jsx("span", { children: review?.published ? "This revision has been published. This review link remains private." : `Prepared by ${publicationName} for ${celebration ? "family " : ""}review.` })
|
|
279
225
|
] }),
|
|
280
|
-
/* @__PURE__ */
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
review.revision.document.media.filter((m) => m.position === "hero").map((m) => /* @__PURE__ */ jsx(PrivatePhoto, { media: m, base }, m.file_id)),
|
|
284
|
-
/* @__PURE__ */ jsx(
|
|
285
|
-
"div",
|
|
286
|
-
{
|
|
287
|
-
className: "sm-review-prose",
|
|
288
|
-
dangerouslySetInnerHTML: { __html: review.revision.content_html }
|
|
289
|
-
}
|
|
290
|
-
),
|
|
291
|
-
review.revision.document.media.filter((m) => m.position !== "hero").map((m) => /* @__PURE__ */ jsx(PrivatePhoto, { media: m, base }, m.file_id))
|
|
292
|
-
] }),
|
|
293
|
-
/* @__PURE__ */ jsxs("nav", { className: "sm-review-actions", "aria-label": "Review actions", children: [
|
|
294
|
-
can("APPROVE") && !review.published && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("approve"), children: review.review_policy === "FACT_CHECK" ? "Confirm fact check" : "Approve draft" }),
|
|
295
|
-
can("REQUEST_CHANGES") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("changes"), children: "Request changes" }),
|
|
296
|
-
can("PROPOSE_EDITS") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("edits"), children: "Suggest edits" }),
|
|
297
|
-
can("ANSWER_QUESTIONS") && review.questions.length > 0 && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("questions"), children: "Answer questions" }),
|
|
298
|
-
can("UPLOAD_MEDIA") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("media"), children: "Add photos" }),
|
|
299
|
-
can("COMMENT") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("comment"), children: "Leave a comment" }),
|
|
300
|
-
can("VIEW_SELECTED_HISTORY") && review.history.length > 0 && /* @__PURE__ */ jsx("button", { onClick: () => setPanel("history"), children: "Shared history" }),
|
|
301
|
-
can("DOWNLOAD_PREVIEW") && /* @__PURE__ */ jsx("button", { onClick: () => window.print(), children: "Print / save preview" })
|
|
302
|
-
] }),
|
|
303
|
-
panel !== "article" && /* @__PURE__ */ jsxs("section", { className: "sm-review-form", "aria-label": "Your response", children: [
|
|
304
|
-
/* @__PURE__ */ jsxs("div", { className: "sm-review-form-heading", children: [
|
|
305
|
-
/* @__PURE__ */ jsx("h2", { children: panel === "approve" ? "Approve this exact draft" : panel === "edits" ? "Propose changes" : panel === "media" ? "Contribute a photograph" : panel === "questions" ? "Your story, in your words" : panel === "history" ? "Selected revision history" : panel === "decline" ? "Decline participation" : panel === "changes" ? "Request changes" : "Message the newsroom" }),
|
|
306
|
-
/* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("article"), children: "Close" })
|
|
226
|
+
/* @__PURE__ */ jsxs("header", { className: "sm-review-masthead", children: [
|
|
227
|
+
nameplateUrl && /* @__PURE__ */ jsx("img", { src: nameplateUrl, alt: "", width: 80, height: 80 }),
|
|
228
|
+
/* @__PURE__ */ jsx("span", { children: review?.publication.name || publicationName })
|
|
307
229
|
] }),
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
"input",
|
|
314
|
-
{
|
|
315
|
-
value: document.title,
|
|
316
|
-
onChange: (e) => setDocument({ ...document, title: e.target.value })
|
|
317
|
-
}
|
|
318
|
-
)
|
|
319
|
-
] }),
|
|
320
|
-
/* @__PURE__ */ jsxs("label", { children: [
|
|
321
|
-
"Dek",
|
|
322
|
-
/* @__PURE__ */ jsx(
|
|
323
|
-
"input",
|
|
324
|
-
{
|
|
325
|
-
value: document.subtitle,
|
|
326
|
-
onChange: (e) => setDocument({ ...document, subtitle: e.target.value })
|
|
327
|
-
}
|
|
328
|
-
)
|
|
329
|
-
] }),
|
|
330
|
-
/* @__PURE__ */ jsxs("label", { children: [
|
|
331
|
-
"Suggested article text",
|
|
332
|
-
/* @__PURE__ */ jsx(
|
|
333
|
-
"textarea",
|
|
334
|
-
{
|
|
335
|
-
rows: 16,
|
|
336
|
-
value: document.content_markdown,
|
|
337
|
-
onChange: (e) => setDocument({
|
|
338
|
-
...document,
|
|
339
|
-
content_markdown: e.target.value
|
|
340
|
-
})
|
|
341
|
-
}
|
|
342
|
-
)
|
|
343
|
-
] }),
|
|
230
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "sm-review-alert", children: error }),
|
|
231
|
+
notice && !(approved && finalEditor && notice === approvalThanks) && /* @__PURE__ */ jsx("p", { role: "status", className: "sm-review-notice", children: notice }),
|
|
232
|
+
verification && /* @__PURE__ */ jsxs("section", { className: "sm-review-form", children: [
|
|
233
|
+
/* @__PURE__ */ jsx("h2", { children: "Verify your email" }),
|
|
234
|
+
/* @__PURE__ */ jsx("p", { children: "The editor requires verification using the email address on your invitation. Your story remains private until verified." }),
|
|
344
235
|
/* @__PURE__ */ jsx(
|
|
345
236
|
"button",
|
|
346
237
|
{
|
|
347
238
|
disabled: busy,
|
|
348
|
-
onClick: () =>
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
239
|
+
onClick: async () => {
|
|
240
|
+
setBusy(true);
|
|
241
|
+
setError("");
|
|
242
|
+
try {
|
|
243
|
+
await request("/verify", {});
|
|
244
|
+
setNotice(
|
|
245
|
+
"A code was sent to the email address chosen by the editor. It expires in ten minutes."
|
|
246
|
+
);
|
|
247
|
+
} catch (e) {
|
|
248
|
+
setError(
|
|
249
|
+
e instanceof Error ? e.message : "Could not send code."
|
|
250
|
+
);
|
|
251
|
+
} finally {
|
|
252
|
+
setBusy(false);
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
children: "Email me a verification code"
|
|
359
256
|
}
|
|
360
|
-
)
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
"form",
|
|
364
|
-
{
|
|
365
|
-
onSubmit: (e) => {
|
|
366
|
-
e.preventDefault();
|
|
367
|
-
void send(
|
|
368
|
-
{ action: "ANSWER_QUESTIONS", answers },
|
|
369
|
-
"Your answers have been saved for editorial review."
|
|
370
|
-
);
|
|
371
|
-
},
|
|
372
|
-
children: [
|
|
373
|
-
/* @__PURE__ */ jsx("p", { children: "All questions are optional unless marked required. Share only what you would like considered for publication." }),
|
|
374
|
-
review.questions.map((q) => /* @__PURE__ */ jsxs("label", { children: [
|
|
375
|
-
q.prompt,
|
|
376
|
-
q.required ? " (required)" : " (optional)",
|
|
377
|
-
/* @__PURE__ */ jsx(
|
|
378
|
-
"textarea",
|
|
379
|
-
{
|
|
380
|
-
required: q.required,
|
|
381
|
-
rows: 3,
|
|
382
|
-
value: answers[q.id] || "",
|
|
383
|
-
onChange: (e) => setAnswers({ ...answers, [q.id]: e.target.value })
|
|
384
|
-
}
|
|
385
|
-
)
|
|
386
|
-
] }, q.id)),
|
|
387
|
-
/* @__PURE__ */ jsx("button", { disabled: busy, children: "Send answers" })
|
|
388
|
-
]
|
|
389
|
-
}
|
|
390
|
-
),
|
|
391
|
-
panel === "metadata" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
392
|
-
/* @__PURE__ */ jsx("p", { children: "Caption and credit changes are proposals for the newsroom; historical captions remain intact." }),
|
|
393
|
-
["caption", "credit", "alt"].map((key) => /* @__PURE__ */ jsxs("label", { children: [
|
|
394
|
-
key,
|
|
395
|
-
/* @__PURE__ */ jsx(
|
|
396
|
-
"input",
|
|
397
|
-
{
|
|
398
|
-
value: mediaInfo[key],
|
|
399
|
-
onChange: (e) => setMediaInfo({ ...mediaInfo, [key]: e.target.value })
|
|
400
|
-
}
|
|
401
|
-
)
|
|
402
|
-
] }, key)),
|
|
403
|
-
/* @__PURE__ */ jsx(
|
|
404
|
-
"button",
|
|
257
|
+
),
|
|
258
|
+
/* @__PURE__ */ jsxs(
|
|
259
|
+
"form",
|
|
405
260
|
{
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
children: [
|
|
429
|
-
/* @__PURE__ */ jsx("p", { children: "JPEG, PNG or WebP photos up to 12 MB; MP4 or WebM videos up to 25 MB. Media remain private until selected and approved by the newsroom." }),
|
|
430
|
-
/* @__PURE__ */ jsxs("label", { children: [
|
|
431
|
-
"Photograph or video",
|
|
432
|
-
/* @__PURE__ */ jsx(
|
|
433
|
-
"input",
|
|
434
|
-
{
|
|
435
|
-
type: "file",
|
|
436
|
-
accept: "image/jpeg,image/png,image/webp,video/mp4,video/webm",
|
|
437
|
-
required: true,
|
|
438
|
-
onChange: (e) => setFile(e.target.files?.[0] || null)
|
|
439
|
-
}
|
|
440
|
-
)
|
|
441
|
-
] }),
|
|
442
|
-
Object.entries({
|
|
443
|
-
caption: "Caption",
|
|
444
|
-
who_is_pictured: "Who is pictured?",
|
|
445
|
-
creator: "Photographer / creator",
|
|
446
|
-
when_taken: "When was it taken?",
|
|
447
|
-
where_taken: "Where was it taken?",
|
|
448
|
-
credit: "Credit line",
|
|
449
|
-
alt: "Alt-text suggestion"
|
|
450
|
-
}).map(([key, label]) => /* @__PURE__ */ jsxs("label", { children: [
|
|
451
|
-
label,
|
|
452
|
-
/* @__PURE__ */ jsx(
|
|
453
|
-
"input",
|
|
454
|
-
{
|
|
455
|
-
value: mediaInfo[key],
|
|
456
|
-
onChange: (e) => setMediaInfo({ ...mediaInfo, [key]: e.target.value })
|
|
457
|
-
}
|
|
458
|
-
)
|
|
459
|
-
] }, key)),
|
|
460
|
-
/* @__PURE__ */ jsxs("label", { className: "sm-review-check", children: [
|
|
461
|
-
/* @__PURE__ */ jsx(
|
|
462
|
-
"input",
|
|
463
|
-
{
|
|
464
|
-
type: "checkbox",
|
|
465
|
-
required: true,
|
|
466
|
-
checked: rights,
|
|
467
|
-
onChange: (e) => setRights(e.target.checked)
|
|
468
|
-
}
|
|
469
|
-
),
|
|
470
|
-
"I confirm that I have the right or permission to provide this media to ",
|
|
471
|
-
review.publication.name,
|
|
472
|
-
" for editorial publication."
|
|
473
|
-
] }),
|
|
474
|
-
/* @__PURE__ */ jsx("button", { disabled: busy || !rights || !file, children: "Upload privately" })
|
|
475
|
-
]
|
|
476
|
-
}
|
|
477
|
-
),
|
|
478
|
-
["approve", "changes", "comment", "decline"].includes(panel) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
479
|
-
panel === "approve" && /* @__PURE__ */ jsxs("p", { children: [
|
|
480
|
-
"You are approving version ",
|
|
481
|
-
review.revision.number,
|
|
482
|
-
". Changes to the article require a new approval.",
|
|
483
|
-
review.review_policy === "SUBJECT_APPROVAL_AUTO_PUBLISH" ? " The editor has configured this version to publish or schedule after the required approvals are received." : " The newsroom will complete its editorial workflow before publication."
|
|
484
|
-
] }),
|
|
485
|
-
panel === "decline" && /* @__PURE__ */ jsx("p", { children: ["FACT_CHECK", "CONTRIBUTOR_REVIEW"].includes(
|
|
486
|
-
review.review_policy
|
|
487
|
-
) ? "You can decline this review. The newsroom may still publish its reporting." : "Declining participation prevents publication of this voluntary announcement." }),
|
|
488
|
-
panel === "comment" && /* @__PURE__ */ jsxs("label", { children: [
|
|
489
|
-
"Comment on",
|
|
490
|
-
/* @__PURE__ */ jsxs(
|
|
491
|
-
"select",
|
|
492
|
-
{
|
|
493
|
-
value: commentTarget,
|
|
494
|
-
onChange: (e) => setCommentTarget(e.target.value),
|
|
495
|
-
children: [
|
|
496
|
-
/* @__PURE__ */ jsx("option", { value: "STORY", children: "Entire story" }),
|
|
497
|
-
review.revision.document.content_markdown.split(/\n\s*\n/).slice(0, 200).map((_, i) => /* @__PURE__ */ jsxs("option", { value: `PARAGRAPH:${i + 1}`, children: [
|
|
498
|
-
"Paragraph ",
|
|
499
|
-
i + 1
|
|
500
|
-
] }, i)),
|
|
501
|
-
review.revision.document.media.map((m, i) => /* @__PURE__ */ jsxs(
|
|
502
|
-
"option",
|
|
261
|
+
onSubmit: async (e) => {
|
|
262
|
+
e.preventDefault();
|
|
263
|
+
setBusy(true);
|
|
264
|
+
setError("");
|
|
265
|
+
try {
|
|
266
|
+
await request("/verify", { code });
|
|
267
|
+
await load();
|
|
268
|
+
setCode("");
|
|
269
|
+
setNotice("Email verified.");
|
|
270
|
+
} catch (e2) {
|
|
271
|
+
setError(
|
|
272
|
+
e2 instanceof Error ? e2.message : "Verification failed."
|
|
273
|
+
);
|
|
274
|
+
} finally {
|
|
275
|
+
setBusy(false);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
children: [
|
|
279
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
280
|
+
"Eight-digit code",
|
|
281
|
+
/* @__PURE__ */ jsx(
|
|
282
|
+
"input",
|
|
503
283
|
{
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
m.contribution_id
|
|
511
|
-
)),
|
|
512
|
-
review.questions.map((q) => /* @__PURE__ */ jsx("option", { value: `QUESTION:${q.id}`, children: q.prompt }, q.id))
|
|
513
|
-
]
|
|
514
|
-
}
|
|
515
|
-
)
|
|
516
|
-
] }),
|
|
517
|
-
/* @__PURE__ */ jsxs("label", { children: [
|
|
518
|
-
panel === "changes" ? "What should change?" : "Message (optional)",
|
|
519
|
-
/* @__PURE__ */ jsx(
|
|
520
|
-
"textarea",
|
|
521
|
-
{
|
|
522
|
-
rows: 5,
|
|
523
|
-
value: message,
|
|
524
|
-
onChange: (e) => setMessage(e.target.value)
|
|
525
|
-
}
|
|
526
|
-
)
|
|
527
|
-
] }),
|
|
528
|
-
/* @__PURE__ */ jsx(
|
|
529
|
-
"button",
|
|
530
|
-
{
|
|
531
|
-
disabled: busy || panel === "changes" && !message.trim() || panel === "comment" && !message.trim(),
|
|
532
|
-
onClick: () => void send(
|
|
533
|
-
{
|
|
534
|
-
action: panel === "approve" ? "APPROVE" : panel === "changes" ? "REQUEST_CHANGES" : panel === "decline" ? "DECLINE" : "COMMENT",
|
|
535
|
-
message: message || null,
|
|
536
|
-
...panel === "comment" ? {
|
|
537
|
-
target: {
|
|
538
|
-
kind: commentTarget.split(":")[0],
|
|
539
|
-
reference: commentTarget.split(":")[1] || null
|
|
284
|
+
inputMode: "numeric",
|
|
285
|
+
autoComplete: "one-time-code",
|
|
286
|
+
pattern: "[0-9]{8}",
|
|
287
|
+
required: true,
|
|
288
|
+
value: code,
|
|
289
|
+
onChange: (e) => setCode(e.target.value)
|
|
540
290
|
}
|
|
541
|
-
|
|
542
|
-
},
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
children: panel === "approve" ? `Approve version ${review.revision.number}` : panel === "changes" ? "Send change request" : panel === "decline" ? "Decline participation" : "Send comment"
|
|
291
|
+
)
|
|
292
|
+
] }),
|
|
293
|
+
/* @__PURE__ */ jsx("button", { disabled: busy, children: "Verify and open preview" })
|
|
294
|
+
]
|
|
546
295
|
}
|
|
547
296
|
)
|
|
548
297
|
] }),
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
/* @__PURE__ */ jsxs("
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
"
|
|
298
|
+
!review && !error && !verification && /* @__PURE__ */ jsx("p", { role: "status", children: "Opening your private preview\u2026" }),
|
|
299
|
+
review && document && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
300
|
+
celebration ? /* @__PURE__ */ jsxs("div", { className: "sm-review-intro", children: [
|
|
301
|
+
review.revision.number > 1 ? /* @__PURE__ */ jsxs("p", { children: [
|
|
302
|
+
/* @__PURE__ */ jsx("strong", { children: "Updated preview" }),
|
|
303
|
+
" \u2014 We incorporated the information you sent us."
|
|
304
|
+
] }) : /* @__PURE__ */ jsx("p", { children: "A special occasion, thoughtfully told. Read your announcement below." }),
|
|
305
|
+
/* @__PURE__ */ jsx("a", { href: "#review-options", children: "Review options" })
|
|
306
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "sm-review-intro", children: [
|
|
307
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
308
|
+
"Prepared for ",
|
|
309
|
+
review.reviewer,
|
|
310
|
+
" \xB7 Version",
|
|
311
|
+
" ",
|
|
312
|
+
review.revision.number
|
|
313
|
+
] }),
|
|
314
|
+
/* @__PURE__ */ jsx("p", { children: ["FACT_CHECK", "CONTRIBUTOR_REVIEW"].includes(
|
|
315
|
+
review.review_policy
|
|
316
|
+
) ? "Please help us check the facts and represent your contribution accurately. The newsroom retains the final editorial decision." : "Please review this announcement. You may suggest changes or decline participation." })
|
|
317
|
+
] }),
|
|
318
|
+
approved && finalEditor && !review.published && /* @__PURE__ */ jsxs("section", { ref: thanksRef, tabIndex: -1, className: "sm-review-thanks", role: "status", children: [
|
|
319
|
+
/* @__PURE__ */ jsx("h2", { children: "Thank you." }),
|
|
320
|
+
/* @__PURE__ */ jsx("p", { children: "We're glad to help commemorate this special occasion." }),
|
|
321
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
322
|
+
"This version has been sent to the ",
|
|
323
|
+
review.publication.name,
|
|
324
|
+
" ",
|
|
325
|
+
"newsroom for final editorial review. It has not been published yet."
|
|
326
|
+
] })
|
|
327
|
+
] }),
|
|
328
|
+
/* @__PURE__ */ jsxs("article", { className: "sm-review-article", children: [
|
|
329
|
+
/* @__PURE__ */ jsxs("p", { className: "sm-review-category", children: [
|
|
330
|
+
/* @__PURE__ */ jsx("span", { children: review.revision.document.section }),
|
|
331
|
+
celebration && /* @__PURE__ */ jsx("span", { children: human(review.celebration_type || "") })
|
|
332
|
+
] }),
|
|
333
|
+
/* @__PURE__ */ jsx("h1", { children: review.revision.document.title }),
|
|
334
|
+
/* @__PURE__ */ jsx("p", { className: "sm-review-dek", children: review.revision.document.subtitle }),
|
|
335
|
+
/* @__PURE__ */ jsx(EditorialNotices, { editorial: review.revision.editorial }),
|
|
336
|
+
review.revision.document.media.filter((m) => m.position === "hero").map((m) => /* @__PURE__ */ jsx(PrivatePhoto, { media: m, base }, m.file_id)),
|
|
337
|
+
celebration && !review.revision.document.media.some(
|
|
338
|
+
(m) => m.position === "hero"
|
|
339
|
+
) && can("UPLOAD_MEDIA") && /* @__PURE__ */ jsxs(
|
|
340
|
+
"aside",
|
|
555
341
|
{
|
|
556
|
-
|
|
557
|
-
|
|
342
|
+
className: "sm-review-photo-invitation",
|
|
343
|
+
"aria-label": "Family photograph",
|
|
558
344
|
children: [
|
|
559
|
-
/* @__PURE__ */
|
|
560
|
-
|
|
561
|
-
"
|
|
562
|
-
|
|
563
|
-
|
|
345
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
346
|
+
/* @__PURE__ */ jsx("strong", { children: "A photograph makes it yours." }),
|
|
347
|
+
/* @__PURE__ */ jsx("p", { children: "Family photograph may be added before publication." })
|
|
348
|
+
] }),
|
|
349
|
+
/* @__PURE__ */ jsx("button", { onClick: () => setPanel("media"), children: "+ Add a photograph" })
|
|
564
350
|
]
|
|
565
351
|
}
|
|
566
|
-
)
|
|
567
|
-
] }),
|
|
568
|
-
/* @__PURE__ */ jsxs("label", { children: [
|
|
569
|
-
"Compare to",
|
|
570
|
-
/* @__PURE__ */ jsx(
|
|
571
|
-
"select",
|
|
572
|
-
{
|
|
573
|
-
value: compareTo || review.revision.id,
|
|
574
|
-
onChange: (e) => setCompareTo(e.target.value),
|
|
575
|
-
children: revisions.map((r) => /* @__PURE__ */ jsxs("option", { value: r.id, children: [
|
|
576
|
-
"Version ",
|
|
577
|
-
r.number
|
|
578
|
-
] }, r.id))
|
|
579
|
-
}
|
|
580
|
-
)
|
|
581
|
-
] }),
|
|
582
|
-
selected && selectedAfter && /* @__PURE__ */ jsx(ReviewDiff, { before: selected, after: selectedAfter }),
|
|
583
|
-
/* @__PURE__ */ jsxs("details", { children: [
|
|
584
|
-
/* @__PURE__ */ jsx("summary", { children: "Read selected revision" }),
|
|
585
|
-
/* @__PURE__ */ jsx("h3", { children: selected?.document.title }),
|
|
586
|
-
/* @__PURE__ */ jsx("p", { children: selected?.document.subtitle }),
|
|
587
|
-
/* @__PURE__ */ jsx(EditorialNotices, { editorial: selected?.editorial }),
|
|
352
|
+
),
|
|
588
353
|
/* @__PURE__ */ jsx(
|
|
589
354
|
"div",
|
|
590
355
|
{
|
|
591
356
|
className: "sm-review-prose",
|
|
592
|
-
dangerouslySetInnerHTML: {
|
|
593
|
-
__html: selected?.content_html || ""
|
|
594
|
-
}
|
|
357
|
+
dangerouslySetInnerHTML: { __html: review.revision.content_html }
|
|
595
358
|
}
|
|
596
359
|
),
|
|
597
|
-
|
|
598
|
-
] })
|
|
599
|
-
] })
|
|
600
|
-
] }),
|
|
601
|
-
review.contributions.length > 0 && /* @__PURE__ */ jsxs("section", { className: "sm-review-contributions", children: [
|
|
602
|
-
/* @__PURE__ */ jsx("h2", { children: "Your contributions and newsroom messages" }),
|
|
603
|
-
review.contributions.map((c) => /* @__PURE__ */ jsxs("div", { children: [
|
|
604
|
-
/* @__PURE__ */ jsxs("p", { children: [
|
|
605
|
-
/* @__PURE__ */ jsx("strong", { children: human(c.kind) }),
|
|
606
|
-
" \xB7 ",
|
|
607
|
-
human(c.state)
|
|
360
|
+
review.revision.document.media.filter((m) => m.position !== "hero").map((m) => /* @__PURE__ */ jsx(PrivatePhoto, { media: m, base }, m.file_id))
|
|
608
361
|
] }),
|
|
609
|
-
|
|
610
|
-
"
|
|
611
|
-
|
|
612
|
-
" ",
|
|
613
|
-
|
|
614
|
-
] }),
|
|
615
|
-
c.payload.message && /* @__PURE__ */ jsx("p", { children: c.payload.message }),
|
|
616
|
-
c.payload.answers && Object.entries(c.payload.answers).map(([q, a]) => /* @__PURE__ */ jsx("p", { children: a }, q)),
|
|
617
|
-
c.kind === "MEDIA" && c.payload.file_id && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
618
|
-
/* @__PURE__ */ jsx(
|
|
619
|
-
PrivatePhoto,
|
|
620
|
-
{
|
|
621
|
-
base,
|
|
622
|
-
media: {
|
|
623
|
-
file_id: c.payload.file_id,
|
|
624
|
-
caption: c.payload.caption || "",
|
|
625
|
-
credit: c.payload.credit || "",
|
|
626
|
-
alt: c.payload.caption || "",
|
|
627
|
-
position: "gallery",
|
|
628
|
-
contribution_id: c.id
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
),
|
|
632
|
-
c.state !== "WITHDRAWN" && can("EDIT_MEDIA_METADATA") && /* @__PURE__ */ jsx(
|
|
362
|
+
celebration && /* @__PURE__ */ jsxs("section", { id: "review-options", className: "sm-review-welcome", children: [
|
|
363
|
+
/* @__PURE__ */ jsx("h2", { children: "Help us make this just right" }),
|
|
364
|
+
/* @__PURE__ */ jsx("p", { children: "We prepared this announcement as a starting point so you don't have to write anything yourself. If everything looks right, you can simply approve it." }),
|
|
365
|
+
/* @__PURE__ */ jsx("p", { children: "If you'd like, you can also correct a detail, add photographs, or tell us a little more about the couple. We'll take care of turning any additional information into the next draft." }),
|
|
366
|
+
can("ANSWER_QUESTIONS") && review.questions.length > 0 && /* @__PURE__ */ jsx(
|
|
633
367
|
"button",
|
|
634
368
|
{
|
|
635
369
|
onClick: () => {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
...mediaInfo,
|
|
639
|
-
caption: c.payload.caption || "",
|
|
640
|
-
credit: c.payload.credit || "",
|
|
641
|
-
alt: c.payload.caption || ""
|
|
642
|
-
});
|
|
643
|
-
setPanel("metadata");
|
|
370
|
+
setMoreQuestions(false);
|
|
371
|
+
setPanel("questions");
|
|
644
372
|
},
|
|
645
|
-
children: "
|
|
373
|
+
children: "Tell Us More"
|
|
646
374
|
}
|
|
647
375
|
),
|
|
648
|
-
|
|
376
|
+
can("DECLINE") && !review.published && /* @__PURE__ */ jsx(
|
|
649
377
|
"button",
|
|
650
378
|
{
|
|
651
|
-
|
|
652
|
-
onClick: () =>
|
|
379
|
+
className: "sm-review-quiet",
|
|
380
|
+
onClick: () => setPanel("decline"),
|
|
381
|
+
children: "Prefer Not to Publish"
|
|
382
|
+
}
|
|
383
|
+
),
|
|
384
|
+
can("COMMENT") && /* @__PURE__ */ jsx("button", { className: "sm-review-quiet", onClick: () => setPanel("comment"), children: "Leave a Comment" })
|
|
385
|
+
] }),
|
|
386
|
+
/* @__PURE__ */ jsxs(
|
|
387
|
+
"nav",
|
|
388
|
+
{
|
|
389
|
+
className: `sm-review-actions${celebration ? " sm-review-concierge-actions" : ""}${panel !== "article" ? " sm-review-actions-editing" : ""}`,
|
|
390
|
+
"aria-label": "Review actions",
|
|
391
|
+
children: [
|
|
392
|
+
can("APPROVE") && !review.published && /* @__PURE__ */ jsx(
|
|
393
|
+
"button",
|
|
653
394
|
{
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
395
|
+
className: "sm-review-primary",
|
|
396
|
+
disabled: busy || approved || review.decision === "DECLINED",
|
|
397
|
+
onClick: approve,
|
|
398
|
+
children: approved ? "Thank you \u2014 Approved" : review.review_policy === "FACT_CHECK" ? "Confirm fact check" : celebration ? "Looks Good \u2014 Approve" : "Approve draft"
|
|
399
|
+
}
|
|
658
400
|
),
|
|
659
|
-
children: "
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
401
|
+
can("REQUEST_CHANGES") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("changes"), children: celebration ? "Suggest a Change" : "Request changes" }),
|
|
402
|
+
celebration && can("PROPOSE_EDITS") && !can("REQUEST_CHANGES") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("edits"), children: "Suggest a Change" }),
|
|
403
|
+
can("UPLOAD_MEDIA") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("media"), children: celebration ? "Add Photos" : "Add photos" }),
|
|
404
|
+
!celebration && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
405
|
+
can("PROPOSE_EDITS") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("edits"), children: "Suggest edits" }),
|
|
406
|
+
can("ANSWER_QUESTIONS") && review.questions.length > 0 && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("questions"), children: "Answer questions" }),
|
|
407
|
+
can("COMMENT") && /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("comment"), children: "Leave a comment" })
|
|
408
|
+
] })
|
|
409
|
+
]
|
|
410
|
+
}
|
|
411
|
+
),
|
|
412
|
+
(can("VIEW_SELECTED_HISTORY") && review.history.length > 0 || can("DOWNLOAD_PREVIEW")) && /* @__PURE__ */ jsxs("div", { className: "sm-review-utilities", children: [
|
|
413
|
+
can("VIEW_SELECTED_HISTORY") && review.history.length > 0 && /* @__PURE__ */ jsx("button", { onClick: () => setPanel("history"), children: "See previous previews" }),
|
|
414
|
+
can("DOWNLOAD_PREVIEW") && /* @__PURE__ */ jsx("button", { onClick: () => window.print(), children: "Print / save preview" })
|
|
415
|
+
] }),
|
|
416
|
+
panel !== "article" && /* @__PURE__ */ jsxs(
|
|
417
|
+
"section",
|
|
418
|
+
{
|
|
419
|
+
ref: responseRef,
|
|
420
|
+
tabIndex: -1,
|
|
421
|
+
className: "sm-review-form",
|
|
422
|
+
"aria-label": "Your response",
|
|
423
|
+
children: [
|
|
424
|
+
/* @__PURE__ */ jsxs("div", { className: "sm-review-form-heading", children: [
|
|
425
|
+
/* @__PURE__ */ jsx("h2", { children: panel === "approve" ? "Approve this exact draft" : panel === "edits" ? "Propose changes" : panel === "media" ? "Contribute a photograph" : panel === "questions" ? "Tell us a little more" : panel === "history" ? "Selected revision history" : panel === "decline" ? "Prefer not to publish" : panel === "changes" ? "Suggest a change" : "Message the newsroom" }),
|
|
426
|
+
/* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("article"), children: "Close" })
|
|
427
|
+
] }),
|
|
428
|
+
panel === "edits" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
429
|
+
/* @__PURE__ */ jsx("p", { children: "Your suggestions will be reviewed by an editor. They do not replace the newsroom\u2019s draft." }),
|
|
430
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
431
|
+
"Headline",
|
|
432
|
+
/* @__PURE__ */ jsx(
|
|
433
|
+
"input",
|
|
434
|
+
{
|
|
435
|
+
value: document.title,
|
|
436
|
+
onChange: (e) => setDocument({ ...document, title: e.target.value })
|
|
437
|
+
}
|
|
438
|
+
)
|
|
439
|
+
] }),
|
|
440
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
441
|
+
"Short introduction",
|
|
442
|
+
/* @__PURE__ */ jsx(
|
|
443
|
+
"input",
|
|
444
|
+
{
|
|
445
|
+
value: document.subtitle,
|
|
446
|
+
onChange: (e) => setDocument({ ...document, subtitle: e.target.value })
|
|
447
|
+
}
|
|
448
|
+
)
|
|
449
|
+
] }),
|
|
450
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
451
|
+
"Suggested article text",
|
|
452
|
+
/* @__PURE__ */ jsx(
|
|
453
|
+
"textarea",
|
|
454
|
+
{
|
|
455
|
+
rows: 16,
|
|
456
|
+
value: document.content_markdown,
|
|
457
|
+
onChange: (e) => setDocument({
|
|
458
|
+
...document,
|
|
459
|
+
content_markdown: e.target.value
|
|
460
|
+
})
|
|
461
|
+
}
|
|
462
|
+
)
|
|
463
|
+
] }),
|
|
464
|
+
/* @__PURE__ */ jsx(
|
|
465
|
+
"button",
|
|
466
|
+
{
|
|
467
|
+
disabled: busy,
|
|
468
|
+
onClick: () => void send(
|
|
469
|
+
{
|
|
470
|
+
action: "PROPOSE_EDITS",
|
|
471
|
+
title: document.title,
|
|
472
|
+
subtitle: document.subtitle,
|
|
473
|
+
content_markdown: document.content_markdown,
|
|
474
|
+
message
|
|
475
|
+
},
|
|
476
|
+
"Your proposed changes have been sent to the newsroom."
|
|
477
|
+
),
|
|
478
|
+
children: "Send proposed changes"
|
|
479
|
+
}
|
|
480
|
+
)
|
|
481
|
+
] }),
|
|
482
|
+
panel === "questions" && /* @__PURE__ */ jsxs(
|
|
483
|
+
"form",
|
|
484
|
+
{
|
|
485
|
+
onSubmit: (e) => {
|
|
486
|
+
e.preventDefault();
|
|
487
|
+
void send(
|
|
488
|
+
{ action: "ANSWER_QUESTIONS", answers },
|
|
489
|
+
"Thank you for sharing. We'll take care of turning your answers into an updated draft."
|
|
490
|
+
);
|
|
491
|
+
},
|
|
492
|
+
children: [
|
|
493
|
+
/* @__PURE__ */ jsx("p", { children: review.questions.some((q) => q.required) ? "Only questions marked required must be answered. Share what you would like considered for publication." : "Completely optional. Even one answer can help us make the announcement more personal." }),
|
|
494
|
+
review.questions.filter((q, i) => moreQuestions || i < 5 || q.required).map((q) => /* @__PURE__ */ jsxs("label", { children: [
|
|
495
|
+
q.prompt,
|
|
496
|
+
q.required ? " (required)" : " (optional)",
|
|
497
|
+
/* @__PURE__ */ jsx(
|
|
498
|
+
"textarea",
|
|
499
|
+
{
|
|
500
|
+
required: q.required,
|
|
501
|
+
rows: 3,
|
|
502
|
+
value: answers[q.id] || "",
|
|
503
|
+
onChange: (e) => setAnswers({ ...answers, [q.id]: e.target.value })
|
|
504
|
+
}
|
|
505
|
+
)
|
|
506
|
+
] }, q.id)),
|
|
507
|
+
/* @__PURE__ */ jsx(
|
|
508
|
+
"button",
|
|
509
|
+
{
|
|
510
|
+
className: "sm-review-primary",
|
|
511
|
+
disabled: busy || !Object.values(answers).some((a) => a.trim()),
|
|
512
|
+
children: "Send These Answers"
|
|
513
|
+
}
|
|
514
|
+
),
|
|
515
|
+
!moreQuestions && review.questions.length > 5 && /* @__PURE__ */ jsx(
|
|
516
|
+
"button",
|
|
517
|
+
{
|
|
518
|
+
type: "button",
|
|
519
|
+
onClick: () => setMoreQuestions(true),
|
|
520
|
+
children: "Answer More Questions"
|
|
521
|
+
}
|
|
522
|
+
)
|
|
523
|
+
]
|
|
524
|
+
}
|
|
525
|
+
),
|
|
526
|
+
panel === "metadata" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
527
|
+
/* @__PURE__ */ jsx("p", { children: "Caption and credit changes are proposals for the newsroom; historical captions remain intact." }),
|
|
528
|
+
["caption", "credit", "alt"].map((key) => /* @__PURE__ */ jsxs("label", { children: [
|
|
529
|
+
key,
|
|
530
|
+
/* @__PURE__ */ jsx(
|
|
531
|
+
"input",
|
|
532
|
+
{
|
|
533
|
+
value: mediaInfo[key],
|
|
534
|
+
onChange: (e) => setMediaInfo({ ...mediaInfo, [key]: e.target.value })
|
|
535
|
+
}
|
|
536
|
+
)
|
|
537
|
+
] }, key)),
|
|
538
|
+
/* @__PURE__ */ jsx(
|
|
539
|
+
"button",
|
|
540
|
+
{
|
|
541
|
+
disabled: busy,
|
|
542
|
+
onClick: () => void send(
|
|
543
|
+
{
|
|
544
|
+
action: "EDIT_MEDIA_METADATA",
|
|
545
|
+
contribution_id: editingMedia,
|
|
546
|
+
caption: mediaInfo.caption,
|
|
547
|
+
credit: mediaInfo.credit,
|
|
548
|
+
alt: mediaInfo.alt
|
|
549
|
+
},
|
|
550
|
+
"Your proposed media descriptions have been sent to the newsroom."
|
|
551
|
+
),
|
|
552
|
+
children: "Propose caption / credit changes"
|
|
553
|
+
}
|
|
554
|
+
)
|
|
555
|
+
] }),
|
|
556
|
+
panel === "media" && /* @__PURE__ */ jsxs(
|
|
557
|
+
"form",
|
|
558
|
+
{
|
|
559
|
+
onSubmit: (e) => {
|
|
560
|
+
e.preventDefault();
|
|
561
|
+
void upload();
|
|
562
|
+
},
|
|
563
|
+
children: [
|
|
564
|
+
/* @__PURE__ */ jsx("p", { children: "JPEG, PNG or WebP photos up to 12 MB; MP4 or WebM videos up to 25 MB. Media remain private until selected and approved by the newsroom." }),
|
|
565
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
566
|
+
"Photograph or video",
|
|
567
|
+
/* @__PURE__ */ jsx(
|
|
568
|
+
"input",
|
|
569
|
+
{
|
|
570
|
+
type: "file",
|
|
571
|
+
accept: "image/jpeg,image/png,image/webp,video/mp4,video/webm",
|
|
572
|
+
required: true,
|
|
573
|
+
onChange: (e) => setFile(e.target.files?.[0] || null)
|
|
574
|
+
}
|
|
575
|
+
)
|
|
576
|
+
] }),
|
|
577
|
+
/* @__PURE__ */ jsx("p", { className: "sm-review-help", children: "Choose a photograph and confirm permission below. All descriptions are optional; we can help with the caption." }),
|
|
578
|
+
Object.entries({
|
|
579
|
+
caption: "Caption (optional)",
|
|
580
|
+
credit: "Photographer / credit (optional)"
|
|
581
|
+
}).map(([key, label]) => /* @__PURE__ */ jsxs("label", { children: [
|
|
582
|
+
label,
|
|
583
|
+
/* @__PURE__ */ jsx(
|
|
584
|
+
"input",
|
|
585
|
+
{
|
|
586
|
+
value: mediaInfo[key],
|
|
587
|
+
onChange: (e) => setMediaInfo({ ...mediaInfo, [key]: e.target.value })
|
|
588
|
+
}
|
|
589
|
+
)
|
|
590
|
+
] }, key)),
|
|
591
|
+
/* @__PURE__ */ jsxs("details", { className: "sm-review-media-details", children: [
|
|
592
|
+
/* @__PURE__ */ jsx("summary", { children: "Add more photograph details (optional)" }),
|
|
593
|
+
Object.entries({
|
|
594
|
+
who_is_pictured: "Who is pictured?",
|
|
595
|
+
creator: "Photographer / creator",
|
|
596
|
+
when_taken: "When was it taken?",
|
|
597
|
+
where_taken: "Where was it taken?",
|
|
598
|
+
alt: "Describe the photograph for readers who cannot see it"
|
|
599
|
+
}).map(([key, label]) => /* @__PURE__ */ jsxs("label", { children: [
|
|
600
|
+
label,
|
|
601
|
+
/* @__PURE__ */ jsx(
|
|
602
|
+
"input",
|
|
603
|
+
{
|
|
604
|
+
value: mediaInfo[key],
|
|
605
|
+
onChange: (e) => setMediaInfo({
|
|
606
|
+
...mediaInfo,
|
|
607
|
+
[key]: e.target.value
|
|
608
|
+
})
|
|
609
|
+
}
|
|
610
|
+
)
|
|
611
|
+
] }, key))
|
|
612
|
+
] }),
|
|
613
|
+
/* @__PURE__ */ jsxs("label", { className: "sm-review-check", children: [
|
|
614
|
+
/* @__PURE__ */ jsx(
|
|
615
|
+
"input",
|
|
616
|
+
{
|
|
617
|
+
type: "checkbox",
|
|
618
|
+
required: true,
|
|
619
|
+
checked: rights,
|
|
620
|
+
onChange: (e) => setRights(e.target.checked)
|
|
621
|
+
}
|
|
622
|
+
),
|
|
623
|
+
"I confirm that I have the right or permission to provide this media to ",
|
|
624
|
+
review.publication.name,
|
|
625
|
+
" for editorial publication."
|
|
626
|
+
] }),
|
|
627
|
+
/* @__PURE__ */ jsx("button", { disabled: busy || !rights || !file, children: "Upload privately" })
|
|
628
|
+
]
|
|
629
|
+
}
|
|
630
|
+
),
|
|
631
|
+
["approve", "changes", "comment", "decline"].includes(panel) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
632
|
+
panel === "approve" && /* @__PURE__ */ jsxs("p", { children: [
|
|
633
|
+
"You are approving version ",
|
|
634
|
+
review.revision.number,
|
|
635
|
+
". Changes to the article require a new approval.",
|
|
636
|
+
review.review_policy === "SUBJECT_APPROVAL_AUTO_PUBLISH" ? " The editor has configured this version to publish or schedule after the required approvals are received." : " The newsroom will complete its editorial workflow before publication."
|
|
637
|
+
] }),
|
|
638
|
+
panel === "decline" && /* @__PURE__ */ jsx("p", { children: ["FACT_CHECK", "CONTRIBUTOR_REVIEW"].includes(
|
|
639
|
+
review.review_policy
|
|
640
|
+
) ? "You can decline this review. The newsroom may still publish its reporting." : "Declining participation prevents publication of this voluntary announcement." }),
|
|
641
|
+
panel === "comment" && /* @__PURE__ */ jsxs("label", { children: [
|
|
642
|
+
"Comment on",
|
|
643
|
+
/* @__PURE__ */ jsxs(
|
|
644
|
+
"select",
|
|
645
|
+
{
|
|
646
|
+
value: commentTarget,
|
|
647
|
+
onChange: (e) => setCommentTarget(e.target.value),
|
|
648
|
+
children: [
|
|
649
|
+
/* @__PURE__ */ jsx("option", { value: "STORY", children: "Entire story" }),
|
|
650
|
+
review.revision.document.content_markdown.split(/\n\s*\n/).slice(0, 200).map((_, i) => /* @__PURE__ */ jsxs("option", { value: `PARAGRAPH:${i + 1}`, children: [
|
|
651
|
+
"Paragraph ",
|
|
652
|
+
i + 1
|
|
653
|
+
] }, i)),
|
|
654
|
+
review.revision.document.media.map((m, i) => /* @__PURE__ */ jsxs(
|
|
655
|
+
"option",
|
|
656
|
+
{
|
|
657
|
+
value: `MEDIA:${m.contribution_id}`,
|
|
658
|
+
children: [
|
|
659
|
+
"Photo / caption ",
|
|
660
|
+
i + 1
|
|
661
|
+
]
|
|
662
|
+
},
|
|
663
|
+
m.contribution_id
|
|
664
|
+
)),
|
|
665
|
+
review.questions.map((q) => /* @__PURE__ */ jsx("option", { value: `QUESTION:${q.id}`, children: q.prompt }, q.id))
|
|
666
|
+
]
|
|
667
|
+
}
|
|
668
|
+
)
|
|
669
|
+
] }),
|
|
670
|
+
panel === "changes" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
671
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
672
|
+
"What would you like to change?",
|
|
673
|
+
/* @__PURE__ */ jsx(
|
|
674
|
+
"select",
|
|
675
|
+
{
|
|
676
|
+
value: correctionKind,
|
|
677
|
+
onChange: (e) => setCorrectionKind(e.target.value),
|
|
678
|
+
children: [
|
|
679
|
+
"Correct a detail",
|
|
680
|
+
"Correct a name",
|
|
681
|
+
"Correct a professional / education detail",
|
|
682
|
+
"Remove something",
|
|
683
|
+
"Rewrite something",
|
|
684
|
+
"Add something",
|
|
685
|
+
"General comment"
|
|
686
|
+
].map((kind) => /* @__PURE__ */ jsx("option", { children: kind }, kind))
|
|
687
|
+
}
|
|
688
|
+
)
|
|
689
|
+
] }),
|
|
690
|
+
/* @__PURE__ */ jsx("p", { children: "A sentence or two is enough. We'll take care of the wording." }),
|
|
691
|
+
can("PROPOSE_EDITS") && /* @__PURE__ */ jsx("button", { onClick: () => setPanel("edits"), children: "Or edit the wording directly" })
|
|
692
|
+
] }),
|
|
693
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
694
|
+
panel === "changes" ? "What should change?" : "Message (optional)",
|
|
695
|
+
/* @__PURE__ */ jsx(
|
|
696
|
+
"textarea",
|
|
697
|
+
{
|
|
698
|
+
rows: 5,
|
|
699
|
+
value: message,
|
|
700
|
+
onChange: (e) => setMessage(e.target.value)
|
|
701
|
+
}
|
|
702
|
+
)
|
|
703
|
+
] }),
|
|
704
|
+
/* @__PURE__ */ jsx(
|
|
705
|
+
"button",
|
|
706
|
+
{
|
|
707
|
+
disabled: busy || panel === "changes" && !message.trim() || panel === "comment" && !message.trim(),
|
|
708
|
+
onClick: () => void send(
|
|
709
|
+
{
|
|
710
|
+
action: panel === "approve" ? "APPROVE" : panel === "changes" ? "REQUEST_CHANGES" : panel === "decline" ? "DECLINE" : "COMMENT",
|
|
711
|
+
message: panel === "changes" ? `${correctionKind}: ${message}` : message || null,
|
|
712
|
+
...panel === "comment" ? {
|
|
713
|
+
target: {
|
|
714
|
+
kind: commentTarget.split(":")[0],
|
|
715
|
+
reference: commentTarget.split(":")[1] || null
|
|
716
|
+
}
|
|
717
|
+
} : {}
|
|
718
|
+
},
|
|
719
|
+
panel === "approve" ? celebration && finalEditor ? approvalThanks : "Your approval has been recorded for this version." : panel === "decline" ? "Thank you for letting us know. The newsroom has received your decision." : "Your message has been sent to the newsroom."
|
|
720
|
+
),
|
|
721
|
+
children: panel === "approve" ? `Approve version ${review.revision.number}` : panel === "changes" ? "Send change request" : panel === "decline" ? "Prefer not to publish" : "Send comment"
|
|
722
|
+
}
|
|
723
|
+
)
|
|
724
|
+
] }),
|
|
725
|
+
panel === "history" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
726
|
+
/* @__PURE__ */ jsx("p", { children: "Only revisions selected by the editor are visible here." }),
|
|
727
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
728
|
+
"Compare from",
|
|
729
|
+
/* @__PURE__ */ jsxs(
|
|
730
|
+
"select",
|
|
731
|
+
{
|
|
732
|
+
value: compare,
|
|
733
|
+
onChange: (e) => setCompare(e.target.value),
|
|
734
|
+
children: [
|
|
735
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Choose a shared revision" }),
|
|
736
|
+
revisions.map((r) => /* @__PURE__ */ jsxs("option", { value: r.id, children: [
|
|
737
|
+
"Version ",
|
|
738
|
+
r.number
|
|
739
|
+
] }, r.id))
|
|
740
|
+
]
|
|
741
|
+
}
|
|
742
|
+
)
|
|
743
|
+
] }),
|
|
744
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
745
|
+
"Compare to",
|
|
746
|
+
/* @__PURE__ */ jsx(
|
|
747
|
+
"select",
|
|
748
|
+
{
|
|
749
|
+
value: compareTo || review.revision.id,
|
|
750
|
+
onChange: (e) => setCompareTo(e.target.value),
|
|
751
|
+
children: revisions.map((r) => /* @__PURE__ */ jsxs("option", { value: r.id, children: [
|
|
752
|
+
"Version ",
|
|
753
|
+
r.number
|
|
754
|
+
] }, r.id))
|
|
755
|
+
}
|
|
756
|
+
)
|
|
757
|
+
] }),
|
|
758
|
+
selected && selectedAfter && /* @__PURE__ */ jsx(ReviewDiff, { before: selected, after: selectedAfter }),
|
|
759
|
+
/* @__PURE__ */ jsxs("details", { children: [
|
|
760
|
+
/* @__PURE__ */ jsx("summary", { children: "Read selected revision" }),
|
|
761
|
+
/* @__PURE__ */ jsx("h3", { children: selected?.document.title }),
|
|
762
|
+
/* @__PURE__ */ jsx("p", { children: selected?.document.subtitle }),
|
|
763
|
+
/* @__PURE__ */ jsx(EditorialNotices, { editorial: selected?.editorial }),
|
|
764
|
+
/* @__PURE__ */ jsx(
|
|
765
|
+
"div",
|
|
766
|
+
{
|
|
767
|
+
className: "sm-review-prose",
|
|
768
|
+
dangerouslySetInnerHTML: {
|
|
769
|
+
__html: selected?.content_html || ""
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
),
|
|
773
|
+
selected?.document.media.map((m) => /* @__PURE__ */ jsx(PrivatePhoto, { media: m, base }, m.file_id))
|
|
774
|
+
] })
|
|
775
|
+
] })
|
|
776
|
+
]
|
|
777
|
+
}
|
|
778
|
+
),
|
|
779
|
+
review.contributions.length > 0 && /* @__PURE__ */ jsxs("section", { className: "sm-review-contributions", children: [
|
|
780
|
+
/* @__PURE__ */ jsx("h2", { children: "Your contributions and newsroom messages" }),
|
|
781
|
+
review.contributions.map((c) => /* @__PURE__ */ jsxs("div", { children: [
|
|
782
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
783
|
+
/* @__PURE__ */ jsx("strong", { children: human(c.kind) }),
|
|
784
|
+
" \xB7 ",
|
|
785
|
+
human(c.state)
|
|
786
|
+
] }),
|
|
787
|
+
c.payload.target && /* @__PURE__ */ jsxs("p", { children: [
|
|
788
|
+
"Regarding ",
|
|
789
|
+
human(c.payload.target.kind),
|
|
790
|
+
" ",
|
|
791
|
+
c.payload.target.reference
|
|
792
|
+
] }),
|
|
793
|
+
c.payload.message && /* @__PURE__ */ jsx("p", { children: c.payload.message }),
|
|
794
|
+
c.payload.answers && Object.entries(c.payload.answers).map(([q, a]) => /* @__PURE__ */ jsx("p", { children: a }, q)),
|
|
795
|
+
c.kind === "MEDIA" && c.payload.file_id && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
796
|
+
/* @__PURE__ */ jsx(
|
|
797
|
+
PrivatePhoto,
|
|
798
|
+
{
|
|
799
|
+
base,
|
|
800
|
+
media: {
|
|
801
|
+
file_id: c.payload.file_id,
|
|
802
|
+
caption: c.payload.caption || "",
|
|
803
|
+
credit: c.payload.credit || "",
|
|
804
|
+
alt: c.payload.caption || "",
|
|
805
|
+
position: "gallery",
|
|
806
|
+
contribution_id: c.id
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
),
|
|
810
|
+
c.state !== "WITHDRAWN" && can("EDIT_MEDIA_METADATA") && /* @__PURE__ */ jsx(
|
|
811
|
+
"button",
|
|
812
|
+
{
|
|
813
|
+
onClick: () => {
|
|
814
|
+
setEditingMedia(c.id);
|
|
815
|
+
setMediaInfo({
|
|
816
|
+
...mediaInfo,
|
|
817
|
+
caption: c.payload.caption || "",
|
|
818
|
+
credit: c.payload.credit || "",
|
|
819
|
+
alt: c.payload.caption || ""
|
|
820
|
+
});
|
|
821
|
+
setPanel("metadata");
|
|
822
|
+
},
|
|
823
|
+
children: "Suggest caption / credit changes"
|
|
824
|
+
}
|
|
825
|
+
),
|
|
826
|
+
c.state !== "WITHDRAWN" && can("UPLOAD_MEDIA") && /* @__PURE__ */ jsx(
|
|
827
|
+
"button",
|
|
828
|
+
{
|
|
829
|
+
disabled: busy,
|
|
830
|
+
onClick: () => void send(
|
|
831
|
+
{
|
|
832
|
+
action: "WITHDRAW_MEDIA",
|
|
833
|
+
contribution_id: c.id
|
|
834
|
+
},
|
|
835
|
+
"Your media has been withdrawn from consideration."
|
|
836
|
+
),
|
|
837
|
+
children: "Withdraw this media"
|
|
838
|
+
}
|
|
839
|
+
)
|
|
840
|
+
] })
|
|
841
|
+
] }, c.id))
|
|
842
|
+
] }),
|
|
843
|
+
!celebration && can("DECLINE") && !review.published && /* @__PURE__ */ jsx("footer", { className: "sm-review-decline", children: /* @__PURE__ */ jsx("button", { disabled: busy, onClick: () => setPanel("decline"), children: "Decline participation / please don\u2019t publish this announcement" }) })
|
|
844
|
+
] })
|
|
845
|
+
]
|
|
846
|
+
}
|
|
847
|
+
);
|
|
668
848
|
}
|
|
669
849
|
function PrivatePhoto({ base, media }) {
|
|
670
850
|
const [url, setUrl] = useState("");
|