Files
study-bible-project/src/utils/importTemplate.js
T
nmemmertandClaude Sonnet 5.5 ec59f7c82d
Build and Push Docker Image / build-and-push (push) Failing after 20s
Import: downloadable Word template for the session list
A blank three-column session list (Session #, Title, Passage) with instructions and
example rows, built in the browser on demand. A test imports the generated file back
through the real importer.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-29 11:18:24 -04:00

64 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// A blank "Session list" Word document for the Import page: a three-column table
// (session number, title, passage) in exactly the shape the importer reads, with a few example
// rows to overwrite. Built in the browser on demand, so the `docx` library only downloads when
// someone actually asks for the template.
import {
Document, Packer, Paragraph, ShadingType, Table, TableCell, TableRow, TextRun, WidthType, HeadingLevel,
} from 'docx';
export const TEMPLATE_FILENAME = 'session-list-template.docx';
// Example rows show each kind of passage the importer understands.
export const TEMPLATE_ROWS = [
['1', 'Paul’s greeting', '1:1–4'],
['2', 'Appointing elders', '1:5–9'],
['3', 'Rebuking false teachers', '1:10–16'],
['4', 'A recap of chapter 1', '—'], // no passage: becomes a divider or intro with no verses
['5', 'Teaching sound doctrine', '2:1–10'],
['6', 'A passage that crosses a chapter', '2:11–3:2'],
];
const cell = (text, { bold = false, shade = false, width } = {}) => new TableCell({
width: { size: width, type: WidthType.PERCENTAGE },
shading: shade ? { type: ShadingType.CLEAR, fill: 'EDE7D9', color: 'auto' } : undefined,
margins: { top: 80, bottom: 80, left: 120, right: 120 },
children: [new Paragraph({ children: [new TextRun({ text, bold })] })],
});
const row = (cells, header = false) => new TableRow({
tableHeader: header,
children: cells.map((text, i) => cell(text, { bold: header, shade: header, width: [15, 55, 30][i] })),
});
const note = (text) => new Paragraph({ spacing: { after: 100 }, children: [new TextRun({ text })] });
export function buildImportTemplateDocument() {
return new Document({
sections: [{
children: [
new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun({ text: 'Session list' })] }),
note('Replace the example rows below with your own, one row per session, then upload this file on the Import page.'),
note('Passage: chapter:verse, like 1:1–4. To cross a chapter, write both chapters, like 2:11–3:2. For a session with no passage (an intro or a recap), write — (a dash).'),
note('You choose the book on the Import page, so leave it out of the Passage column. Keep the three columns, and delete any example rows you don’t need.'),
new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
rows: [row(['Session #', 'Title', 'Passage'], true), ...TEMPLATE_ROWS.map((r) => row(r))],
}),
],
}],
});
}
// Builds the template and hands it to the browser as a download.
export async function downloadImportTemplate() {
const blob = await Packer.toBlob(buildImportTemplateDocument());
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = TEMPLATE_FILENAME;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
}