@fonderie/react-courier-admin-screens 0.1.0 → 0.2.0
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 +3 -3
- package/dist/index.cjs +9 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +12 -5
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Pre-built React screens for the Fonderie courier admin API —
|
|
4
4
|
`TemplateListScreen` and `TemplateEditorScreen` — built on
|
|
5
|
-
[`@fonderie/react-courier-admin`](https://github.com/
|
|
5
|
+
[`@fonderie/react-courier-admin`](https://github.com/fonderiejs/sdk/tree/main/packages/react-courier-admin)
|
|
6
6
|
hooks. Plain HTML elements, inline styles you can override, zero UI library
|
|
7
7
|
dependency.
|
|
8
8
|
|
|
@@ -48,7 +48,7 @@ without the markup? Use `@fonderie/react-courier-admin`'s hooks directly.
|
|
|
48
48
|
You've shipped this plumbing before — auth, teams, billing, messaging —
|
|
49
49
|
and the next project will ask for it again. Fonderie packages it once:
|
|
50
50
|
plain TypeScript modules for
|
|
51
|
-
[`@fonderie/core`](https://github.com/
|
|
51
|
+
[`@fonderie/core`](https://github.com/fonderiejs/sdk/tree/main/packages/core),
|
|
52
52
|
PostgreSQL-backed, self-hosted, MIT. No external control plane, no
|
|
53
53
|
per-seat anything. Register the modules you need; skip the ones you don't.
|
|
54
54
|
|
|
@@ -58,7 +58,7 @@ design system whenever you outgrow it — `@fonderie/react-courier-admin`'s
|
|
|
58
58
|
hooks work standalone.
|
|
59
59
|
|
|
60
60
|
Browse the whole set at
|
|
61
|
-
[
|
|
61
|
+
[fonderiejs/sdk](https://github.com/fonderiejs/sdk) · follow
|
|
62
62
|
[@fonderiejs](https://x.com/fonderiejs)
|
|
63
63
|
|
|
64
64
|
## License
|
package/dist/index.cjs
CHANGED
|
@@ -36,8 +36,10 @@ function TemplateEditorScreen({
|
|
|
36
36
|
onSaved
|
|
37
37
|
}) {
|
|
38
38
|
const { template, isLoading, error, refresh } = (0, import_react_courier_admin.useTemplate)(client, type, locale);
|
|
39
|
-
const { saveTemplate
|
|
39
|
+
const { saveTemplate } = (0, import_react_courier_admin.useTemplates)(client);
|
|
40
40
|
const { revisions, rollback } = (0, import_react_courier_admin.useTemplateRevisions)(client, type, locale);
|
|
41
|
+
const [isSaving, setIsSaving] = (0, import_react.useState)(false);
|
|
42
|
+
const [saveError, setSaveError] = (0, import_react.useState)(null);
|
|
41
43
|
const [subject, setSubject] = (0, import_react.useState)("");
|
|
42
44
|
const [html, setHtml] = (0, import_react.useState)("");
|
|
43
45
|
const [text, setText] = (0, import_react.useState)("");
|
|
@@ -51,6 +53,8 @@ function TemplateEditorScreen({
|
|
|
51
53
|
}, [template]);
|
|
52
54
|
const handleSubmit = async (event) => {
|
|
53
55
|
event.preventDefault();
|
|
56
|
+
setIsSaving(true);
|
|
57
|
+
setSaveError(null);
|
|
54
58
|
try {
|
|
55
59
|
const input = { text, active };
|
|
56
60
|
if (subject) input.subject = subject;
|
|
@@ -59,7 +63,10 @@ function TemplateEditorScreen({
|
|
|
59
63
|
await saveTemplate(type, input, locale);
|
|
60
64
|
await refresh();
|
|
61
65
|
onSaved?.();
|
|
62
|
-
} catch {
|
|
66
|
+
} catch (err) {
|
|
67
|
+
setSaveError(err);
|
|
68
|
+
} finally {
|
|
69
|
+
setIsSaving(false);
|
|
63
70
|
}
|
|
64
71
|
};
|
|
65
72
|
if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.status, children: "Loading template\u2026" });
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/screens/TemplateEditorScreen.tsx","../src/screens/TemplateListScreen.tsx"],"sourcesContent":["export type { ITemplateEditorScreenProps, ITemplateListScreenProps } from './screens';\nexport { TemplateEditorScreen, TemplateListScreen } from './screens';\n","import type { CourierAdminClient, ISetTemplateInput } from '@fonderie/client';\nimport { useSaveTemplate, useTemplate, useTemplateRevisions } from '@fonderie/react-courier-admin';\nimport type { CSSProperties, FormEvent } from 'react';\nimport { useEffect, useState } from 'react';\n\nexport interface ITemplateEditorScreenProps {\n\tclient: CourierAdminClient;\n\ttype: string;\n\tlocale?: string | null;\n\tonSaved?: () => void;\n}\n\nexport function TemplateEditorScreen({\n\tclient,\n\ttype,\n\tlocale,\n\tonSaved,\n}: ITemplateEditorScreenProps) {\n\tconst { template, isLoading, error, refresh } = useTemplate(client, type, locale);\n\tconst { saveTemplate, isLoading: isSaving, error: saveError } = useSaveTemplate(client);\n\tconst { revisions, rollback } = useTemplateRevisions(client, type, locale);\n\n\tconst [subject, setSubject] = useState('');\n\tconst [html, setHtml] = useState('');\n\tconst [text, setText] = useState('');\n\tconst [active, setActive] = useState(true);\n\n\tuseEffect(() => {\n\t\tif (!template) return;\n\t\tsetSubject(template.subject ?? '');\n\t\tsetHtml(template.html ?? '');\n\t\tsetText(template.text);\n\t\tsetActive(template.active);\n\t}, [template]);\n\n\tconst handleSubmit = async (event: FormEvent) => {\n\t\tevent.preventDefault();\n\t\ttry {\n\t\t\tconst input: ISetTemplateInput = { text, active };\n\t\t\tif (subject) input.subject = subject;\n\t\t\tif (html) input.html = html;\n\t\t\tif (template?.version !== undefined) input.ifVersion = template.version;\n\t\t\tawait saveTemplate(type, input, locale);\n\t\t\tawait refresh();\n\t\t\tonSaved?.();\n\t\t} catch {\n\t\t\t// Surfaced via `saveError` from useSaveTemplate.\n\t\t}\n\t};\n\n\tif (isLoading) return <p style={styles.status}>Loading template…</p>;\n\tif (error)\n\t\treturn (\n\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t{error.explanation}\n\t\t\t</p>\n\t\t);\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h1 style={styles.title}>{type}</h1>\n\t\t\t<p style={styles.meta}>\n\t\t\t\t{locale ?? 'base'} · v{template?.version ?? 1}\n\t\t\t</p>\n\n\t\t\t<form style={styles.form} onSubmit={handleSubmit}>\n\t\t\t\t<label style={styles.label} htmlFor=\"template-subject\">\n\t\t\t\t\tSubject\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"template-subject\"\n\t\t\t\t\tstyle={styles.input}\n\t\t\t\t\tvalue={subject}\n\t\t\t\t\tonChange={(event) => setSubject(event.target.value)}\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.label} htmlFor=\"template-html\">\n\t\t\t\t\tHTML body\n\t\t\t\t</label>\n\t\t\t\t<textarea\n\t\t\t\t\tid=\"template-html\"\n\t\t\t\t\tstyle={styles.textarea}\n\t\t\t\t\tvalue={html}\n\t\t\t\t\tonChange={(event) => setHtml(event.target.value)}\n\t\t\t\t\trows={8}\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.label} htmlFor=\"template-text\">\n\t\t\t\t\tPlain-text body\n\t\t\t\t</label>\n\t\t\t\t<textarea\n\t\t\t\t\tid=\"template-text\"\n\t\t\t\t\tstyle={styles.textarea}\n\t\t\t\t\tvalue={text}\n\t\t\t\t\tonChange={(event) => setText(event.target.value)}\n\t\t\t\t\trows={4}\n\t\t\t\t\trequired\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.checkboxLabel}>\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tchecked={active}\n\t\t\t\t\t\tonChange={(event) => setActive(event.target.checked)}\n\t\t\t\t\t/>\n\t\t\t\t\tActive\n\t\t\t\t</label>\n\n\t\t\t\t{saveError && (\n\t\t\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t\t\t{saveError.explanation}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\n\t\t\t\t<button type=\"submit\" disabled={isSaving} style={styles.button}>\n\t\t\t\t\t{isSaving ? 'Saving…' : 'Save'}\n\t\t\t\t</button>\n\t\t\t</form>\n\n\t\t\t{revisions.length > 0 && (\n\t\t\t\t<div style={styles.revisions}>\n\t\t\t\t\t<h2 style={styles.subtitle}>History</h2>\n\t\t\t\t\t<ul style={styles.list}>\n\t\t\t\t\t\t{revisions.map((rev) => (\n\t\t\t\t\t\t\t<li key={rev.version} style={styles.row}>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\tv{rev.version} — {rev.actor ?? 'unknown'} —{' '}\n\t\t\t\t\t\t\t\t\t{new Date(rev.createdAt).toLocaleString()}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => rollback(rev.version)}\n\t\t\t\t\t\t\t\t\tstyle={styles.rollbackButton}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRoll back\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nconst styles: Record<string, CSSProperties> = {\n\tcontainer: { padding: 24, maxWidth: 640 },\n\ttitle: { fontSize: 24, fontWeight: 700 },\n\tmeta: { fontSize: 13, color: '#666', marginBottom: 16 },\n\tstatus: { padding: 24, textAlign: 'center', color: '#666' },\n\terror: { color: '#e11d48', marginBottom: 12, fontSize: 14 },\n\tform: { display: 'flex', flexDirection: 'column', gap: 4 },\n\tlabel: { fontSize: 13, fontWeight: 600, marginTop: 12 },\n\tinput: { border: '1px solid #ddd', borderRadius: 8, padding: 10, fontSize: 14 },\n\ttextarea: {\n\t\tborder: '1px solid #ddd',\n\t\tborderRadius: 8,\n\t\tpadding: 10,\n\t\tfontSize: 14,\n\t\tfontFamily: 'monospace',\n\t},\n\tcheckboxLabel: { display: 'flex', alignItems: 'center', gap: 8, marginTop: 12, fontSize: 14 },\n\tbutton: {\n\t\tmarginTop: 16,\n\t\tbackgroundColor: '#000',\n\t\tcolor: '#fff',\n\t\tpadding: '10px 20px',\n\t\tborderRadius: 8,\n\t\tborder: 'none',\n\t\tfontSize: 14,\n\t\tfontWeight: 600,\n\t\tcursor: 'pointer',\n\t\talignSelf: 'flex-start',\n\t},\n\trevisions: { marginTop: 32 },\n\tsubtitle: { fontSize: 16, fontWeight: 600, marginBottom: 8 },\n\tlist: { listStyle: 'none', padding: 0, margin: 0 },\n\trow: {\n\t\tdisplay: 'flex',\n\t\tjustifyContent: 'space-between',\n\t\talignItems: 'center',\n\t\tpadding: '8px 0',\n\t\tborderBottom: '1px solid #eee',\n\t\tfontSize: 13,\n\t},\n\trollbackButton: {\n\t\tbackground: 'none',\n\t\tborder: '1px solid #ddd',\n\t\tborderRadius: 8,\n\t\tpadding: '4px 10px',\n\t\tfontSize: 12,\n\t\tcursor: 'pointer',\n\t},\n};\n","import type { CourierAdminClient, ITemplateEntry } from '@fonderie/client';\nimport { useTemplates } from '@fonderie/react-courier-admin';\nimport type { CSSProperties } from 'react';\n\nexport interface ITemplateListScreenProps {\n\tclient: CourierAdminClient;\n\tonSelectTemplate?: (template: ITemplateEntry) => void;\n}\n\nexport function TemplateListScreen({ client, onSelectTemplate }: ITemplateListScreenProps) {\n\tconst { templates, isLoading, error } = useTemplates(client);\n\n\tif (isLoading) return <p style={styles.status}>Loading templates…</p>;\n\tif (error)\n\t\treturn (\n\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t{error.explanation}\n\t\t\t</p>\n\t\t);\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h1 style={styles.title}>Templates</h1>\n\t\t\t<ul style={styles.list}>\n\t\t\t\t{templates.map((template) => (\n\t\t\t\t\t<li key={`${template.type}:${template.locale ?? 'base'}`} style={styles.row}>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => onSelectTemplate?.(template)}\n\t\t\t\t\t\t\tstyle={styles.rowButton}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span style={styles.type}>{template.type}</span>\n\t\t\t\t\t\t\t<span style={styles.locale}>{template.locale ?? 'base'}</span>\n\t\t\t\t\t\t\t<span style={template.active ? styles.active : styles.inactive}>\n\t\t\t\t\t\t\t\t{template.active ? 'Active' : 'Inactive'}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\t\t</div>\n\t);\n}\n\nconst styles: Record<string, CSSProperties> = {\n\tcontainer: { padding: 24, maxWidth: 640 },\n\ttitle: { fontSize: 24, fontWeight: 700, marginBottom: 16 },\n\tstatus: { padding: 24, textAlign: 'center', color: '#666' },\n\terror: { color: '#e11d48', marginBottom: 12, fontSize: 14 },\n\tlist: { listStyle: 'none', padding: 0, margin: 0 },\n\trow: { borderBottom: '1px solid #eee' },\n\trowButton: {\n\t\twidth: '100%',\n\t\tdisplay: 'flex',\n\t\tjustifyContent: 'space-between',\n\t\talignItems: 'center',\n\t\tpadding: '12px 0',\n\t\tbackground: 'none',\n\t\tborder: 'none',\n\t\tcursor: 'pointer',\n\t\ttextAlign: 'left',\n\t},\n\ttype: { fontSize: 14, fontWeight: 600, flex: 1 },\n\tlocale: { fontSize: 13, color: '#666', marginRight: 16 },\n\tactive: { fontSize: 12, color: '#16a34a' },\n\tinactive: { fontSize: 12, color: '#999' },\n};\n"],"mappings":"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","names":["import_react_courier_admin","import_jsx_runtime","styles"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/screens/TemplateEditorScreen.tsx","../src/screens/TemplateListScreen.tsx"],"sourcesContent":["export type { ITemplateEditorScreenProps, ITemplateListScreenProps } from './screens';\nexport { TemplateEditorScreen, TemplateListScreen } from './screens';\n","import type { CourierAdminClient, FonderieApiError, ISetTemplateInput } from '@fonderie/client';\nimport { useTemplate, useTemplateRevisions, useTemplates } from '@fonderie/react-courier-admin';\nimport type { CSSProperties, FormEvent } from 'react';\nimport { useEffect, useState } from 'react';\n\nexport interface ITemplateEditorScreenProps {\n\tclient: CourierAdminClient;\n\ttype: string;\n\tlocale?: string | null;\n\tonSaved?: () => void;\n}\n\nexport function TemplateEditorScreen({\n\tclient,\n\ttype,\n\tlocale,\n\tonSaved,\n}: ITemplateEditorScreenProps) {\n\tconst { template, isLoading, error, refresh } = useTemplate(client, type, locale);\n\t// Saves go through the list hook (which re-fetches the template list after\n\t// each write); mounting it adds a template-list fetch to this single-template\n\t// editor — acceptable for an admin dashboard. Its isLoading/error track that\n\t// list fetch, so the save action keeps local state.\n\tconst { saveTemplate } = useTemplates(client);\n\tconst { revisions, rollback } = useTemplateRevisions(client, type, locale);\n\tconst [isSaving, setIsSaving] = useState(false);\n\tconst [saveError, setSaveError] = useState<FonderieApiError | null>(null);\n\n\tconst [subject, setSubject] = useState('');\n\tconst [html, setHtml] = useState('');\n\tconst [text, setText] = useState('');\n\tconst [active, setActive] = useState(true);\n\n\tuseEffect(() => {\n\t\tif (!template) return;\n\t\tsetSubject(template.subject ?? '');\n\t\tsetHtml(template.html ?? '');\n\t\tsetText(template.text);\n\t\tsetActive(template.active);\n\t}, [template]);\n\n\tconst handleSubmit = async (event: FormEvent) => {\n\t\tevent.preventDefault();\n\t\tsetIsSaving(true);\n\t\tsetSaveError(null);\n\t\ttry {\n\t\t\tconst input: ISetTemplateInput = { text, active };\n\t\t\tif (subject) input.subject = subject;\n\t\t\tif (html) input.html = html;\n\t\t\tif (template?.version !== undefined) input.ifVersion = template.version;\n\t\t\tawait saveTemplate(type, input, locale);\n\t\t\t// The list hook refreshes its own list; this screen renders the single\n\t\t\t// template, so re-read it too.\n\t\t\tawait refresh();\n\t\t\tonSaved?.();\n\t\t} catch (err) {\n\t\t\t// useTemplates normalizes every failure to FonderieApiError before throwing.\n\t\t\tsetSaveError(err as FonderieApiError);\n\t\t} finally {\n\t\t\tsetIsSaving(false);\n\t\t}\n\t};\n\n\tif (isLoading) return <p style={styles.status}>Loading template…</p>;\n\tif (error)\n\t\treturn (\n\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t{error.explanation}\n\t\t\t</p>\n\t\t);\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h1 style={styles.title}>{type}</h1>\n\t\t\t<p style={styles.meta}>\n\t\t\t\t{locale ?? 'base'} · v{template?.version ?? 1}\n\t\t\t</p>\n\n\t\t\t<form style={styles.form} onSubmit={handleSubmit}>\n\t\t\t\t<label style={styles.label} htmlFor=\"template-subject\">\n\t\t\t\t\tSubject\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"template-subject\"\n\t\t\t\t\tstyle={styles.input}\n\t\t\t\t\tvalue={subject}\n\t\t\t\t\tonChange={(event) => setSubject(event.target.value)}\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.label} htmlFor=\"template-html\">\n\t\t\t\t\tHTML body\n\t\t\t\t</label>\n\t\t\t\t<textarea\n\t\t\t\t\tid=\"template-html\"\n\t\t\t\t\tstyle={styles.textarea}\n\t\t\t\t\tvalue={html}\n\t\t\t\t\tonChange={(event) => setHtml(event.target.value)}\n\t\t\t\t\trows={8}\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.label} htmlFor=\"template-text\">\n\t\t\t\t\tPlain-text body\n\t\t\t\t</label>\n\t\t\t\t<textarea\n\t\t\t\t\tid=\"template-text\"\n\t\t\t\t\tstyle={styles.textarea}\n\t\t\t\t\tvalue={text}\n\t\t\t\t\tonChange={(event) => setText(event.target.value)}\n\t\t\t\t\trows={4}\n\t\t\t\t\trequired\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.checkboxLabel}>\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tchecked={active}\n\t\t\t\t\t\tonChange={(event) => setActive(event.target.checked)}\n\t\t\t\t\t/>\n\t\t\t\t\tActive\n\t\t\t\t</label>\n\n\t\t\t\t{saveError && (\n\t\t\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t\t\t{saveError.explanation}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\n\t\t\t\t<button type=\"submit\" disabled={isSaving} style={styles.button}>\n\t\t\t\t\t{isSaving ? 'Saving…' : 'Save'}\n\t\t\t\t</button>\n\t\t\t</form>\n\n\t\t\t{revisions.length > 0 && (\n\t\t\t\t<div style={styles.revisions}>\n\t\t\t\t\t<h2 style={styles.subtitle}>History</h2>\n\t\t\t\t\t<ul style={styles.list}>\n\t\t\t\t\t\t{revisions.map((rev) => (\n\t\t\t\t\t\t\t<li key={rev.version} style={styles.row}>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\tv{rev.version} — {rev.actor ?? 'unknown'} —{' '}\n\t\t\t\t\t\t\t\t\t{new Date(rev.createdAt).toLocaleString()}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => rollback(rev.version)}\n\t\t\t\t\t\t\t\t\tstyle={styles.rollbackButton}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRoll back\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nconst styles: Record<string, CSSProperties> = {\n\tcontainer: { padding: 24, maxWidth: 640 },\n\ttitle: { fontSize: 24, fontWeight: 700 },\n\tmeta: { fontSize: 13, color: '#666', marginBottom: 16 },\n\tstatus: { padding: 24, textAlign: 'center', color: '#666' },\n\terror: { color: '#e11d48', marginBottom: 12, fontSize: 14 },\n\tform: { display: 'flex', flexDirection: 'column', gap: 4 },\n\tlabel: { fontSize: 13, fontWeight: 600, marginTop: 12 },\n\tinput: { border: '1px solid #ddd', borderRadius: 8, padding: 10, fontSize: 14 },\n\ttextarea: {\n\t\tborder: '1px solid #ddd',\n\t\tborderRadius: 8,\n\t\tpadding: 10,\n\t\tfontSize: 14,\n\t\tfontFamily: 'monospace',\n\t},\n\tcheckboxLabel: { display: 'flex', alignItems: 'center', gap: 8, marginTop: 12, fontSize: 14 },\n\tbutton: {\n\t\tmarginTop: 16,\n\t\tbackgroundColor: '#000',\n\t\tcolor: '#fff',\n\t\tpadding: '10px 20px',\n\t\tborderRadius: 8,\n\t\tborder: 'none',\n\t\tfontSize: 14,\n\t\tfontWeight: 600,\n\t\tcursor: 'pointer',\n\t\talignSelf: 'flex-start',\n\t},\n\trevisions: { marginTop: 32 },\n\tsubtitle: { fontSize: 16, fontWeight: 600, marginBottom: 8 },\n\tlist: { listStyle: 'none', padding: 0, margin: 0 },\n\trow: {\n\t\tdisplay: 'flex',\n\t\tjustifyContent: 'space-between',\n\t\talignItems: 'center',\n\t\tpadding: '8px 0',\n\t\tborderBottom: '1px solid #eee',\n\t\tfontSize: 13,\n\t},\n\trollbackButton: {\n\t\tbackground: 'none',\n\t\tborder: '1px solid #ddd',\n\t\tborderRadius: 8,\n\t\tpadding: '4px 10px',\n\t\tfontSize: 12,\n\t\tcursor: 'pointer',\n\t},\n};\n","import type { CourierAdminClient, ITemplateEntry } from '@fonderie/client';\nimport { useTemplates } from '@fonderie/react-courier-admin';\nimport type { CSSProperties } from 'react';\n\nexport interface ITemplateListScreenProps {\n\tclient: CourierAdminClient;\n\tonSelectTemplate?: (template: ITemplateEntry) => void;\n}\n\nexport function TemplateListScreen({ client, onSelectTemplate }: ITemplateListScreenProps) {\n\tconst { templates, isLoading, error } = useTemplates(client);\n\n\tif (isLoading) return <p style={styles.status}>Loading templates…</p>;\n\tif (error)\n\t\treturn (\n\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t{error.explanation}\n\t\t\t</p>\n\t\t);\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h1 style={styles.title}>Templates</h1>\n\t\t\t<ul style={styles.list}>\n\t\t\t\t{templates.map((template) => (\n\t\t\t\t\t<li key={`${template.type}:${template.locale ?? 'base'}`} style={styles.row}>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => onSelectTemplate?.(template)}\n\t\t\t\t\t\t\tstyle={styles.rowButton}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span style={styles.type}>{template.type}</span>\n\t\t\t\t\t\t\t<span style={styles.locale}>{template.locale ?? 'base'}</span>\n\t\t\t\t\t\t\t<span style={template.active ? styles.active : styles.inactive}>\n\t\t\t\t\t\t\t\t{template.active ? 'Active' : 'Inactive'}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\t\t</div>\n\t);\n}\n\nconst styles: Record<string, CSSProperties> = {\n\tcontainer: { padding: 24, maxWidth: 640 },\n\ttitle: { fontSize: 24, fontWeight: 700, marginBottom: 16 },\n\tstatus: { padding: 24, textAlign: 'center', color: '#666' },\n\terror: { color: '#e11d48', marginBottom: 12, fontSize: 14 },\n\tlist: { listStyle: 'none', padding: 0, margin: 0 },\n\trow: { borderBottom: '1px solid #eee' },\n\trowButton: {\n\t\twidth: '100%',\n\t\tdisplay: 'flex',\n\t\tjustifyContent: 'space-between',\n\t\talignItems: 'center',\n\t\tpadding: '12px 0',\n\t\tbackground: 'none',\n\t\tborder: 'none',\n\t\tcursor: 'pointer',\n\t\ttextAlign: 'left',\n\t},\n\ttype: { fontSize: 14, fontWeight: 600, flex: 1 },\n\tlocale: { fontSize: 13, color: '#666', marginRight: 16 },\n\tactive: { fontSize: 12, color: '#16a34a' },\n\tinactive: { fontSize: 12, color: '#999' },\n};\n"],"mappings":"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","names":["import_react_courier_admin","import_jsx_runtime","styles"]}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/screens/TemplateEditorScreen.tsx
|
|
2
|
-
import {
|
|
2
|
+
import { useTemplate, useTemplateRevisions, useTemplates } from "@fonderie/react-courier-admin";
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
function TemplateEditorScreen({
|
|
@@ -9,8 +9,10 @@ function TemplateEditorScreen({
|
|
|
9
9
|
onSaved
|
|
10
10
|
}) {
|
|
11
11
|
const { template, isLoading, error, refresh } = useTemplate(client, type, locale);
|
|
12
|
-
const { saveTemplate
|
|
12
|
+
const { saveTemplate } = useTemplates(client);
|
|
13
13
|
const { revisions, rollback } = useTemplateRevisions(client, type, locale);
|
|
14
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
15
|
+
const [saveError, setSaveError] = useState(null);
|
|
14
16
|
const [subject, setSubject] = useState("");
|
|
15
17
|
const [html, setHtml] = useState("");
|
|
16
18
|
const [text, setText] = useState("");
|
|
@@ -24,6 +26,8 @@ function TemplateEditorScreen({
|
|
|
24
26
|
}, [template]);
|
|
25
27
|
const handleSubmit = async (event) => {
|
|
26
28
|
event.preventDefault();
|
|
29
|
+
setIsSaving(true);
|
|
30
|
+
setSaveError(null);
|
|
27
31
|
try {
|
|
28
32
|
const input = { text, active };
|
|
29
33
|
if (subject) input.subject = subject;
|
|
@@ -32,7 +36,10 @@ function TemplateEditorScreen({
|
|
|
32
36
|
await saveTemplate(type, input, locale);
|
|
33
37
|
await refresh();
|
|
34
38
|
onSaved?.();
|
|
35
|
-
} catch {
|
|
39
|
+
} catch (err) {
|
|
40
|
+
setSaveError(err);
|
|
41
|
+
} finally {
|
|
42
|
+
setIsSaving(false);
|
|
36
43
|
}
|
|
37
44
|
};
|
|
38
45
|
if (isLoading) return /* @__PURE__ */ jsx("p", { style: styles.status, children: "Loading template\u2026" });
|
|
@@ -169,10 +176,10 @@ var styles = {
|
|
|
169
176
|
};
|
|
170
177
|
|
|
171
178
|
// src/screens/TemplateListScreen.tsx
|
|
172
|
-
import { useTemplates } from "@fonderie/react-courier-admin";
|
|
179
|
+
import { useTemplates as useTemplates2 } from "@fonderie/react-courier-admin";
|
|
173
180
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
174
181
|
function TemplateListScreen({ client, onSelectTemplate }) {
|
|
175
|
-
const { templates, isLoading, error } =
|
|
182
|
+
const { templates, isLoading, error } = useTemplates2(client);
|
|
176
183
|
if (isLoading) return /* @__PURE__ */ jsx2("p", { style: styles2.status, children: "Loading templates\u2026" });
|
|
177
184
|
if (error)
|
|
178
185
|
return /* @__PURE__ */ jsx2("p", { style: styles2.error, role: "alert", children: error.explanation });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/screens/TemplateEditorScreen.tsx","../src/screens/TemplateListScreen.tsx"],"sourcesContent":["import type { CourierAdminClient, ISetTemplateInput } from '@fonderie/client';\nimport { useSaveTemplate, useTemplate, useTemplateRevisions } from '@fonderie/react-courier-admin';\nimport type { CSSProperties, FormEvent } from 'react';\nimport { useEffect, useState } from 'react';\n\nexport interface ITemplateEditorScreenProps {\n\tclient: CourierAdminClient;\n\ttype: string;\n\tlocale?: string | null;\n\tonSaved?: () => void;\n}\n\nexport function TemplateEditorScreen({\n\tclient,\n\ttype,\n\tlocale,\n\tonSaved,\n}: ITemplateEditorScreenProps) {\n\tconst { template, isLoading, error, refresh } = useTemplate(client, type, locale);\n\tconst { saveTemplate, isLoading: isSaving, error: saveError } = useSaveTemplate(client);\n\tconst { revisions, rollback } = useTemplateRevisions(client, type, locale);\n\n\tconst [subject, setSubject] = useState('');\n\tconst [html, setHtml] = useState('');\n\tconst [text, setText] = useState('');\n\tconst [active, setActive] = useState(true);\n\n\tuseEffect(() => {\n\t\tif (!template) return;\n\t\tsetSubject(template.subject ?? '');\n\t\tsetHtml(template.html ?? '');\n\t\tsetText(template.text);\n\t\tsetActive(template.active);\n\t}, [template]);\n\n\tconst handleSubmit = async (event: FormEvent) => {\n\t\tevent.preventDefault();\n\t\ttry {\n\t\t\tconst input: ISetTemplateInput = { text, active };\n\t\t\tif (subject) input.subject = subject;\n\t\t\tif (html) input.html = html;\n\t\t\tif (template?.version !== undefined) input.ifVersion = template.version;\n\t\t\tawait saveTemplate(type, input, locale);\n\t\t\tawait refresh();\n\t\t\tonSaved?.();\n\t\t} catch {\n\t\t\t// Surfaced via `saveError` from useSaveTemplate.\n\t\t}\n\t};\n\n\tif (isLoading) return <p style={styles.status}>Loading template…</p>;\n\tif (error)\n\t\treturn (\n\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t{error.explanation}\n\t\t\t</p>\n\t\t);\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h1 style={styles.title}>{type}</h1>\n\t\t\t<p style={styles.meta}>\n\t\t\t\t{locale ?? 'base'} · v{template?.version ?? 1}\n\t\t\t</p>\n\n\t\t\t<form style={styles.form} onSubmit={handleSubmit}>\n\t\t\t\t<label style={styles.label} htmlFor=\"template-subject\">\n\t\t\t\t\tSubject\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"template-subject\"\n\t\t\t\t\tstyle={styles.input}\n\t\t\t\t\tvalue={subject}\n\t\t\t\t\tonChange={(event) => setSubject(event.target.value)}\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.label} htmlFor=\"template-html\">\n\t\t\t\t\tHTML body\n\t\t\t\t</label>\n\t\t\t\t<textarea\n\t\t\t\t\tid=\"template-html\"\n\t\t\t\t\tstyle={styles.textarea}\n\t\t\t\t\tvalue={html}\n\t\t\t\t\tonChange={(event) => setHtml(event.target.value)}\n\t\t\t\t\trows={8}\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.label} htmlFor=\"template-text\">\n\t\t\t\t\tPlain-text body\n\t\t\t\t</label>\n\t\t\t\t<textarea\n\t\t\t\t\tid=\"template-text\"\n\t\t\t\t\tstyle={styles.textarea}\n\t\t\t\t\tvalue={text}\n\t\t\t\t\tonChange={(event) => setText(event.target.value)}\n\t\t\t\t\trows={4}\n\t\t\t\t\trequired\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.checkboxLabel}>\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tchecked={active}\n\t\t\t\t\t\tonChange={(event) => setActive(event.target.checked)}\n\t\t\t\t\t/>\n\t\t\t\t\tActive\n\t\t\t\t</label>\n\n\t\t\t\t{saveError && (\n\t\t\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t\t\t{saveError.explanation}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\n\t\t\t\t<button type=\"submit\" disabled={isSaving} style={styles.button}>\n\t\t\t\t\t{isSaving ? 'Saving…' : 'Save'}\n\t\t\t\t</button>\n\t\t\t</form>\n\n\t\t\t{revisions.length > 0 && (\n\t\t\t\t<div style={styles.revisions}>\n\t\t\t\t\t<h2 style={styles.subtitle}>History</h2>\n\t\t\t\t\t<ul style={styles.list}>\n\t\t\t\t\t\t{revisions.map((rev) => (\n\t\t\t\t\t\t\t<li key={rev.version} style={styles.row}>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\tv{rev.version} — {rev.actor ?? 'unknown'} —{' '}\n\t\t\t\t\t\t\t\t\t{new Date(rev.createdAt).toLocaleString()}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => rollback(rev.version)}\n\t\t\t\t\t\t\t\t\tstyle={styles.rollbackButton}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRoll back\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nconst styles: Record<string, CSSProperties> = {\n\tcontainer: { padding: 24, maxWidth: 640 },\n\ttitle: { fontSize: 24, fontWeight: 700 },\n\tmeta: { fontSize: 13, color: '#666', marginBottom: 16 },\n\tstatus: { padding: 24, textAlign: 'center', color: '#666' },\n\terror: { color: '#e11d48', marginBottom: 12, fontSize: 14 },\n\tform: { display: 'flex', flexDirection: 'column', gap: 4 },\n\tlabel: { fontSize: 13, fontWeight: 600, marginTop: 12 },\n\tinput: { border: '1px solid #ddd', borderRadius: 8, padding: 10, fontSize: 14 },\n\ttextarea: {\n\t\tborder: '1px solid #ddd',\n\t\tborderRadius: 8,\n\t\tpadding: 10,\n\t\tfontSize: 14,\n\t\tfontFamily: 'monospace',\n\t},\n\tcheckboxLabel: { display: 'flex', alignItems: 'center', gap: 8, marginTop: 12, fontSize: 14 },\n\tbutton: {\n\t\tmarginTop: 16,\n\t\tbackgroundColor: '#000',\n\t\tcolor: '#fff',\n\t\tpadding: '10px 20px',\n\t\tborderRadius: 8,\n\t\tborder: 'none',\n\t\tfontSize: 14,\n\t\tfontWeight: 600,\n\t\tcursor: 'pointer',\n\t\talignSelf: 'flex-start',\n\t},\n\trevisions: { marginTop: 32 },\n\tsubtitle: { fontSize: 16, fontWeight: 600, marginBottom: 8 },\n\tlist: { listStyle: 'none', padding: 0, margin: 0 },\n\trow: {\n\t\tdisplay: 'flex',\n\t\tjustifyContent: 'space-between',\n\t\talignItems: 'center',\n\t\tpadding: '8px 0',\n\t\tborderBottom: '1px solid #eee',\n\t\tfontSize: 13,\n\t},\n\trollbackButton: {\n\t\tbackground: 'none',\n\t\tborder: '1px solid #ddd',\n\t\tborderRadius: 8,\n\t\tpadding: '4px 10px',\n\t\tfontSize: 12,\n\t\tcursor: 'pointer',\n\t},\n};\n","import type { CourierAdminClient, ITemplateEntry } from '@fonderie/client';\nimport { useTemplates } from '@fonderie/react-courier-admin';\nimport type { CSSProperties } from 'react';\n\nexport interface ITemplateListScreenProps {\n\tclient: CourierAdminClient;\n\tonSelectTemplate?: (template: ITemplateEntry) => void;\n}\n\nexport function TemplateListScreen({ client, onSelectTemplate }: ITemplateListScreenProps) {\n\tconst { templates, isLoading, error } = useTemplates(client);\n\n\tif (isLoading) return <p style={styles.status}>Loading templates…</p>;\n\tif (error)\n\t\treturn (\n\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t{error.explanation}\n\t\t\t</p>\n\t\t);\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h1 style={styles.title}>Templates</h1>\n\t\t\t<ul style={styles.list}>\n\t\t\t\t{templates.map((template) => (\n\t\t\t\t\t<li key={`${template.type}:${template.locale ?? 'base'}`} style={styles.row}>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => onSelectTemplate?.(template)}\n\t\t\t\t\t\t\tstyle={styles.rowButton}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span style={styles.type}>{template.type}</span>\n\t\t\t\t\t\t\t<span style={styles.locale}>{template.locale ?? 'base'}</span>\n\t\t\t\t\t\t\t<span style={template.active ? styles.active : styles.inactive}>\n\t\t\t\t\t\t\t\t{template.active ? 'Active' : 'Inactive'}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\t\t</div>\n\t);\n}\n\nconst styles: Record<string, CSSProperties> = {\n\tcontainer: { padding: 24, maxWidth: 640 },\n\ttitle: { fontSize: 24, fontWeight: 700, marginBottom: 16 },\n\tstatus: { padding: 24, textAlign: 'center', color: '#666' },\n\terror: { color: '#e11d48', marginBottom: 12, fontSize: 14 },\n\tlist: { listStyle: 'none', padding: 0, margin: 0 },\n\trow: { borderBottom: '1px solid #eee' },\n\trowButton: {\n\t\twidth: '100%',\n\t\tdisplay: 'flex',\n\t\tjustifyContent: 'space-between',\n\t\talignItems: 'center',\n\t\tpadding: '12px 0',\n\t\tbackground: 'none',\n\t\tborder: 'none',\n\t\tcursor: 'pointer',\n\t\ttextAlign: 'left',\n\t},\n\ttype: { fontSize: 14, fontWeight: 600, flex: 1 },\n\tlocale: { fontSize: 13, color: '#666', marginRight: 16 },\n\tactive: { fontSize: 12, color: '#16a34a' },\n\tinactive: { fontSize: 12, color: '#999' },\n};\n"],"mappings":"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","names":["jsx","jsxs","styles"]}
|
|
1
|
+
{"version":3,"sources":["../src/screens/TemplateEditorScreen.tsx","../src/screens/TemplateListScreen.tsx"],"sourcesContent":["import type { CourierAdminClient, FonderieApiError, ISetTemplateInput } from '@fonderie/client';\nimport { useTemplate, useTemplateRevisions, useTemplates } from '@fonderie/react-courier-admin';\nimport type { CSSProperties, FormEvent } from 'react';\nimport { useEffect, useState } from 'react';\n\nexport interface ITemplateEditorScreenProps {\n\tclient: CourierAdminClient;\n\ttype: string;\n\tlocale?: string | null;\n\tonSaved?: () => void;\n}\n\nexport function TemplateEditorScreen({\n\tclient,\n\ttype,\n\tlocale,\n\tonSaved,\n}: ITemplateEditorScreenProps) {\n\tconst { template, isLoading, error, refresh } = useTemplate(client, type, locale);\n\t// Saves go through the list hook (which re-fetches the template list after\n\t// each write); mounting it adds a template-list fetch to this single-template\n\t// editor — acceptable for an admin dashboard. Its isLoading/error track that\n\t// list fetch, so the save action keeps local state.\n\tconst { saveTemplate } = useTemplates(client);\n\tconst { revisions, rollback } = useTemplateRevisions(client, type, locale);\n\tconst [isSaving, setIsSaving] = useState(false);\n\tconst [saveError, setSaveError] = useState<FonderieApiError | null>(null);\n\n\tconst [subject, setSubject] = useState('');\n\tconst [html, setHtml] = useState('');\n\tconst [text, setText] = useState('');\n\tconst [active, setActive] = useState(true);\n\n\tuseEffect(() => {\n\t\tif (!template) return;\n\t\tsetSubject(template.subject ?? '');\n\t\tsetHtml(template.html ?? '');\n\t\tsetText(template.text);\n\t\tsetActive(template.active);\n\t}, [template]);\n\n\tconst handleSubmit = async (event: FormEvent) => {\n\t\tevent.preventDefault();\n\t\tsetIsSaving(true);\n\t\tsetSaveError(null);\n\t\ttry {\n\t\t\tconst input: ISetTemplateInput = { text, active };\n\t\t\tif (subject) input.subject = subject;\n\t\t\tif (html) input.html = html;\n\t\t\tif (template?.version !== undefined) input.ifVersion = template.version;\n\t\t\tawait saveTemplate(type, input, locale);\n\t\t\t// The list hook refreshes its own list; this screen renders the single\n\t\t\t// template, so re-read it too.\n\t\t\tawait refresh();\n\t\t\tonSaved?.();\n\t\t} catch (err) {\n\t\t\t// useTemplates normalizes every failure to FonderieApiError before throwing.\n\t\t\tsetSaveError(err as FonderieApiError);\n\t\t} finally {\n\t\t\tsetIsSaving(false);\n\t\t}\n\t};\n\n\tif (isLoading) return <p style={styles.status}>Loading template…</p>;\n\tif (error)\n\t\treturn (\n\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t{error.explanation}\n\t\t\t</p>\n\t\t);\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h1 style={styles.title}>{type}</h1>\n\t\t\t<p style={styles.meta}>\n\t\t\t\t{locale ?? 'base'} · v{template?.version ?? 1}\n\t\t\t</p>\n\n\t\t\t<form style={styles.form} onSubmit={handleSubmit}>\n\t\t\t\t<label style={styles.label} htmlFor=\"template-subject\">\n\t\t\t\t\tSubject\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"template-subject\"\n\t\t\t\t\tstyle={styles.input}\n\t\t\t\t\tvalue={subject}\n\t\t\t\t\tonChange={(event) => setSubject(event.target.value)}\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.label} htmlFor=\"template-html\">\n\t\t\t\t\tHTML body\n\t\t\t\t</label>\n\t\t\t\t<textarea\n\t\t\t\t\tid=\"template-html\"\n\t\t\t\t\tstyle={styles.textarea}\n\t\t\t\t\tvalue={html}\n\t\t\t\t\tonChange={(event) => setHtml(event.target.value)}\n\t\t\t\t\trows={8}\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.label} htmlFor=\"template-text\">\n\t\t\t\t\tPlain-text body\n\t\t\t\t</label>\n\t\t\t\t<textarea\n\t\t\t\t\tid=\"template-text\"\n\t\t\t\t\tstyle={styles.textarea}\n\t\t\t\t\tvalue={text}\n\t\t\t\t\tonChange={(event) => setText(event.target.value)}\n\t\t\t\t\trows={4}\n\t\t\t\t\trequired\n\t\t\t\t/>\n\n\t\t\t\t<label style={styles.checkboxLabel}>\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tchecked={active}\n\t\t\t\t\t\tonChange={(event) => setActive(event.target.checked)}\n\t\t\t\t\t/>\n\t\t\t\t\tActive\n\t\t\t\t</label>\n\n\t\t\t\t{saveError && (\n\t\t\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t\t\t{saveError.explanation}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\n\t\t\t\t<button type=\"submit\" disabled={isSaving} style={styles.button}>\n\t\t\t\t\t{isSaving ? 'Saving…' : 'Save'}\n\t\t\t\t</button>\n\t\t\t</form>\n\n\t\t\t{revisions.length > 0 && (\n\t\t\t\t<div style={styles.revisions}>\n\t\t\t\t\t<h2 style={styles.subtitle}>History</h2>\n\t\t\t\t\t<ul style={styles.list}>\n\t\t\t\t\t\t{revisions.map((rev) => (\n\t\t\t\t\t\t\t<li key={rev.version} style={styles.row}>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\tv{rev.version} — {rev.actor ?? 'unknown'} —{' '}\n\t\t\t\t\t\t\t\t\t{new Date(rev.createdAt).toLocaleString()}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => rollback(rev.version)}\n\t\t\t\t\t\t\t\t\tstyle={styles.rollbackButton}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRoll back\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nconst styles: Record<string, CSSProperties> = {\n\tcontainer: { padding: 24, maxWidth: 640 },\n\ttitle: { fontSize: 24, fontWeight: 700 },\n\tmeta: { fontSize: 13, color: '#666', marginBottom: 16 },\n\tstatus: { padding: 24, textAlign: 'center', color: '#666' },\n\terror: { color: '#e11d48', marginBottom: 12, fontSize: 14 },\n\tform: { display: 'flex', flexDirection: 'column', gap: 4 },\n\tlabel: { fontSize: 13, fontWeight: 600, marginTop: 12 },\n\tinput: { border: '1px solid #ddd', borderRadius: 8, padding: 10, fontSize: 14 },\n\ttextarea: {\n\t\tborder: '1px solid #ddd',\n\t\tborderRadius: 8,\n\t\tpadding: 10,\n\t\tfontSize: 14,\n\t\tfontFamily: 'monospace',\n\t},\n\tcheckboxLabel: { display: 'flex', alignItems: 'center', gap: 8, marginTop: 12, fontSize: 14 },\n\tbutton: {\n\t\tmarginTop: 16,\n\t\tbackgroundColor: '#000',\n\t\tcolor: '#fff',\n\t\tpadding: '10px 20px',\n\t\tborderRadius: 8,\n\t\tborder: 'none',\n\t\tfontSize: 14,\n\t\tfontWeight: 600,\n\t\tcursor: 'pointer',\n\t\talignSelf: 'flex-start',\n\t},\n\trevisions: { marginTop: 32 },\n\tsubtitle: { fontSize: 16, fontWeight: 600, marginBottom: 8 },\n\tlist: { listStyle: 'none', padding: 0, margin: 0 },\n\trow: {\n\t\tdisplay: 'flex',\n\t\tjustifyContent: 'space-between',\n\t\talignItems: 'center',\n\t\tpadding: '8px 0',\n\t\tborderBottom: '1px solid #eee',\n\t\tfontSize: 13,\n\t},\n\trollbackButton: {\n\t\tbackground: 'none',\n\t\tborder: '1px solid #ddd',\n\t\tborderRadius: 8,\n\t\tpadding: '4px 10px',\n\t\tfontSize: 12,\n\t\tcursor: 'pointer',\n\t},\n};\n","import type { CourierAdminClient, ITemplateEntry } from '@fonderie/client';\nimport { useTemplates } from '@fonderie/react-courier-admin';\nimport type { CSSProperties } from 'react';\n\nexport interface ITemplateListScreenProps {\n\tclient: CourierAdminClient;\n\tonSelectTemplate?: (template: ITemplateEntry) => void;\n}\n\nexport function TemplateListScreen({ client, onSelectTemplate }: ITemplateListScreenProps) {\n\tconst { templates, isLoading, error } = useTemplates(client);\n\n\tif (isLoading) return <p style={styles.status}>Loading templates…</p>;\n\tif (error)\n\t\treturn (\n\t\t\t<p style={styles.error} role=\"alert\">\n\t\t\t\t{error.explanation}\n\t\t\t</p>\n\t\t);\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h1 style={styles.title}>Templates</h1>\n\t\t\t<ul style={styles.list}>\n\t\t\t\t{templates.map((template) => (\n\t\t\t\t\t<li key={`${template.type}:${template.locale ?? 'base'}`} style={styles.row}>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => onSelectTemplate?.(template)}\n\t\t\t\t\t\t\tstyle={styles.rowButton}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span style={styles.type}>{template.type}</span>\n\t\t\t\t\t\t\t<span style={styles.locale}>{template.locale ?? 'base'}</span>\n\t\t\t\t\t\t\t<span style={template.active ? styles.active : styles.inactive}>\n\t\t\t\t\t\t\t\t{template.active ? 'Active' : 'Inactive'}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\t\t</div>\n\t);\n}\n\nconst styles: Record<string, CSSProperties> = {\n\tcontainer: { padding: 24, maxWidth: 640 },\n\ttitle: { fontSize: 24, fontWeight: 700, marginBottom: 16 },\n\tstatus: { padding: 24, textAlign: 'center', color: '#666' },\n\terror: { color: '#e11d48', marginBottom: 12, fontSize: 14 },\n\tlist: { listStyle: 'none', padding: 0, margin: 0 },\n\trow: { borderBottom: '1px solid #eee' },\n\trowButton: {\n\t\twidth: '100%',\n\t\tdisplay: 'flex',\n\t\tjustifyContent: 'space-between',\n\t\talignItems: 'center',\n\t\tpadding: '12px 0',\n\t\tbackground: 'none',\n\t\tborder: 'none',\n\t\tcursor: 'pointer',\n\t\ttextAlign: 'left',\n\t},\n\ttype: { fontSize: 14, fontWeight: 600, flex: 1 },\n\tlocale: { fontSize: 13, color: '#666', marginRight: 16 },\n\tactive: { fontSize: 12, color: '#16a34a' },\n\tinactive: { fontSize: 12, color: '#999' },\n};\n"],"mappings":"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","names":["useTemplates","jsx","jsxs","styles"]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonderie/react-courier-admin-screens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Pre-built React screens for the Fonderie courier admin API — template list, template editor with revision history and rollback.",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"
|
|
6
|
+
"fonderiejs",
|
|
7
7
|
"react",
|
|
8
8
|
"courier",
|
|
9
9
|
"templates",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"react": ">=18.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@types/node": "^
|
|
47
|
-
"@types/react": "^
|
|
48
|
-
"react": "^
|
|
46
|
+
"@types/node": "^26.2.0",
|
|
47
|
+
"@types/react": "^19.2.18",
|
|
48
|
+
"react": "^19.2.8",
|
|
49
49
|
"tsup": "^8.5.1",
|
|
50
50
|
"typescript": "^6.0.3"
|
|
51
51
|
},
|