@codeandink/payload-ink 0.0.7-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +64 -0
  3. package/dist/audits/freshness.d.ts +11 -0
  4. package/dist/audits/freshness.d.ts.map +1 -0
  5. package/dist/audits/freshness.js +89 -0
  6. package/dist/audits/freshness.js.map +1 -0
  7. package/dist/audits/seo.d.ts +4 -0
  8. package/dist/audits/seo.d.ts.map +1 -0
  9. package/dist/audits/seo.js +128 -0
  10. package/dist/audits/seo.js.map +1 -0
  11. package/dist/client.d.ts +3 -0
  12. package/dist/client.d.ts.map +1 -0
  13. package/dist/client.js +18 -0
  14. package/dist/client.js.map +1 -0
  15. package/dist/collections/Actions.d.ts +3 -0
  16. package/dist/collections/Actions.d.ts.map +1 -0
  17. package/dist/collections/Actions.js +56 -0
  18. package/dist/collections/Actions.js.map +1 -0
  19. package/dist/collections/Audits.d.ts +3 -0
  20. package/dist/collections/Audits.d.ts.map +1 -0
  21. package/dist/collections/Audits.js +69 -0
  22. package/dist/collections/Audits.js.map +1 -0
  23. package/dist/collections/Insights.d.ts +3 -0
  24. package/dist/collections/Insights.d.ts.map +1 -0
  25. package/dist/collections/Insights.js +99 -0
  26. package/dist/collections/Insights.js.map +1 -0
  27. package/dist/collections/OnboardingProfile.d.ts +3 -0
  28. package/dist/collections/OnboardingProfile.d.ts.map +1 -0
  29. package/dist/collections/OnboardingProfile.js +174 -0
  30. package/dist/collections/OnboardingProfile.js.map +1 -0
  31. package/dist/components/AnalyticsPanel.d.ts +2 -0
  32. package/dist/components/AnalyticsPanel.d.ts.map +1 -0
  33. package/dist/components/AnalyticsPanel.js +151 -0
  34. package/dist/components/AnalyticsPanel.js.map +1 -0
  35. package/dist/components/AuditPanel.d.ts +4 -0
  36. package/dist/components/AuditPanel.d.ts.map +1 -0
  37. package/dist/components/AuditPanel.js +463 -0
  38. package/dist/components/AuditPanel.js.map +1 -0
  39. package/dist/components/AuditsPanel.d.ts +2 -0
  40. package/dist/components/AuditsPanel.d.ts.map +1 -0
  41. package/dist/components/AuditsPanel.js +229 -0
  42. package/dist/components/AuditsPanel.js.map +1 -0
  43. package/dist/components/DigestPanel.d.ts +2 -0
  44. package/dist/components/DigestPanel.d.ts.map +1 -0
  45. package/dist/components/DigestPanel.js +320 -0
  46. package/dist/components/DigestPanel.js.map +1 -0
  47. package/dist/components/FreshnessPanel.d.ts +4 -0
  48. package/dist/components/FreshnessPanel.d.ts.map +1 -0
  49. package/dist/components/FreshnessPanel.js +224 -0
  50. package/dist/components/FreshnessPanel.js.map +1 -0
  51. package/dist/components/InkGradeCell.d.ts +4 -0
  52. package/dist/components/InkGradeCell.d.ts.map +1 -0
  53. package/dist/components/InkGradeCell.js +32 -0
  54. package/dist/components/InkGradeCell.js.map +1 -0
  55. package/dist/components/OnboardingFlow.d.ts +2 -0
  56. package/dist/components/OnboardingFlow.d.ts.map +1 -0
  57. package/dist/components/OnboardingFlow.js +406 -0
  58. package/dist/components/OnboardingFlow.js.map +1 -0
  59. package/dist/components/index.d.ts +8 -0
  60. package/dist/components/index.d.ts.map +1 -0
  61. package/dist/components/index.js +18 -0
  62. package/dist/components/index.js.map +1 -0
  63. package/dist/endpoints/analytics.d.ts +9 -0
  64. package/dist/endpoints/analytics.d.ts.map +1 -0
  65. package/dist/endpoints/analytics.js +68 -0
  66. package/dist/endpoints/analytics.js.map +1 -0
  67. package/dist/endpoints/auditChanges.d.ts +9 -0
  68. package/dist/endpoints/auditChanges.d.ts.map +1 -0
  69. package/dist/endpoints/auditChanges.js +52 -0
  70. package/dist/endpoints/auditChanges.js.map +1 -0
  71. package/dist/endpoints/auditStatus.d.ts +6 -0
  72. package/dist/endpoints/auditStatus.d.ts.map +1 -0
  73. package/dist/endpoints/auditStatus.js +24 -0
  74. package/dist/endpoints/auditStatus.js.map +1 -0
  75. package/dist/endpoints/config.d.ts +8 -0
  76. package/dist/endpoints/config.d.ts.map +1 -0
  77. package/dist/endpoints/config.js +12 -0
  78. package/dist/endpoints/config.js.map +1 -0
  79. package/dist/endpoints/digestPreflight.d.ts +8 -0
  80. package/dist/endpoints/digestPreflight.d.ts.map +1 -0
  81. package/dist/endpoints/digestPreflight.js +79 -0
  82. package/dist/endpoints/digestPreflight.js.map +1 -0
  83. package/dist/endpoints/ga4Test.d.ts +8 -0
  84. package/dist/endpoints/ga4Test.d.ts.map +1 -0
  85. package/dist/endpoints/ga4Test.js +38 -0
  86. package/dist/endpoints/ga4Test.js.map +1 -0
  87. package/dist/endpoints/insights.d.ts +8 -0
  88. package/dist/endpoints/insights.d.ts.map +1 -0
  89. package/dist/endpoints/insights.js +53 -0
  90. package/dist/endpoints/insights.js.map +1 -0
  91. package/dist/endpoints/onboarding.d.ts +4 -0
  92. package/dist/endpoints/onboarding.d.ts.map +1 -0
  93. package/dist/endpoints/onboarding.js +64 -0
  94. package/dist/endpoints/onboarding.js.map +1 -0
  95. package/dist/endpoints/runAudit.d.ts +12 -0
  96. package/dist/endpoints/runAudit.d.ts.map +1 -0
  97. package/dist/endpoints/runAudit.js +174 -0
  98. package/dist/endpoints/runAudit.js.map +1 -0
  99. package/dist/endpoints/runFreshnessAudit.d.ts +13 -0
  100. package/dist/endpoints/runFreshnessAudit.d.ts.map +1 -0
  101. package/dist/endpoints/runFreshnessAudit.js +143 -0
  102. package/dist/endpoints/runFreshnessAudit.js.map +1 -0
  103. package/dist/endpoints/sendDigest.d.ts +10 -0
  104. package/dist/endpoints/sendDigest.d.ts.map +1 -0
  105. package/dist/endpoints/sendDigest.js +259 -0
  106. package/dist/endpoints/sendDigest.js.map +1 -0
  107. package/dist/index.d.ts +4 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +6 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/lib/computeGrade.d.ts +8 -0
  112. package/dist/lib/computeGrade.d.ts.map +1 -0
  113. package/dist/lib/computeGrade.js +48 -0
  114. package/dist/lib/computeGrade.js.map +1 -0
  115. package/dist/plugin.d.ts +28 -0
  116. package/dist/plugin.d.ts.map +1 -0
  117. package/dist/plugin.js +168 -0
  118. package/dist/plugin.js.map +1 -0
  119. package/dist/types.d.ts +99 -0
  120. package/dist/types.d.ts.map +1 -0
  121. package/dist/types.js +3 -0
  122. package/dist/types.js.map +1 -0
  123. package/package.json +75 -0
@@ -0,0 +1,229 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.AuditsPanel = AuditsPanel;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const AuditPanel_js_1 = require("./AuditPanel.js");
8
+ const FreshnessPanel_js_1 = require("./FreshnessPanel.js");
9
+ const ink = {
10
+ bg: '#0a0a0a',
11
+ surface: '#141414',
12
+ border: '#262626',
13
+ borderStrong: '#3a3a3a',
14
+ text: '#fafafa',
15
+ textMuted: '#a3a3a3',
16
+ textSubtle: '#737373',
17
+ };
18
+ const gradeColor = {
19
+ A: '#22c55e',
20
+ B: '#84cc16',
21
+ C: '#eab308',
22
+ D: '#f97316',
23
+ F: '#ef4444',
24
+ };
25
+ const mono = "'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
26
+ function AuditsPanel() {
27
+ const [tab, setTab] = (0, react_1.useState)('seo');
28
+ const [seoGrade, setSeoGrade] = (0, react_1.useState)(null);
29
+ const [freshGrade, setFreshGrade] = (0, react_1.useState)(null);
30
+ (0, react_1.useEffect)(() => {
31
+ let cancelled = false;
32
+ fetch('/api/ink-audits?where[type][equals]=seo&limit=1&sort=-createdAt&depth=0')
33
+ .then((r) => (r.ok ? r.json() : null))
34
+ .then((data) => {
35
+ if (cancelled || !data?.docs?.[0])
36
+ return;
37
+ setSeoGrade(data.docs[0].grade ?? null);
38
+ })
39
+ .catch(() => { });
40
+ fetch('/api/ink-audits?where[type][equals]=freshness&limit=1&sort=-createdAt&depth=0')
41
+ .then((r) => (r.ok ? r.json() : null))
42
+ .then((data) => {
43
+ if (cancelled || !data?.docs?.[0])
44
+ return;
45
+ setFreshGrade(data.docs[0].grade ?? null);
46
+ })
47
+ .catch(() => { });
48
+ return () => {
49
+ cancelled = true;
50
+ };
51
+ }, []);
52
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
53
+ background: ink.bg,
54
+ color: ink.text,
55
+ fontFamily: mono,
56
+ padding: '24px',
57
+ border: `1px solid ${ink.border}`,
58
+ maxWidth: '780px',
59
+ margin: '24px 0',
60
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
61
+ display: 'flex',
62
+ justifyContent: 'space-between',
63
+ alignItems: 'center',
64
+ borderBottom: `1px solid ${ink.border}`,
65
+ paddingBottom: '12px',
66
+ }, children: (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'baseline', gap: '12px' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: '11px', letterSpacing: '0.15em', color: ink.textMuted, fontWeight: 700 }, children: "INK" }), (0, jsx_runtime_1.jsx)("span", { style: { color: ink.textSubtle }, children: "/" }), (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '11px', letterSpacing: '0.1em', color: ink.text, textTransform: 'uppercase' }, children: "Intelligence" })] }) }), (0, jsx_runtime_1.jsxs)("div", { style: {
67
+ display: 'flex',
68
+ gap: '0',
69
+ borderBottom: `1px solid ${ink.border}`,
70
+ marginTop: '8px',
71
+ }, children: [(0, jsx_runtime_1.jsx)(TabButton, { label: "SEO", grade: seoGrade, active: tab === 'seo', onClick: () => setTab('seo') }), (0, jsx_runtime_1.jsx)(TabButton, { label: "Freshness", grade: freshGrade, active: tab === 'freshness', onClick: () => setTab('freshness') }), (0, jsx_runtime_1.jsx)(TabButton, { label: "Insights", grade: null, active: tab === 'insights', onClick: () => setTab('insights') })] }), (0, jsx_runtime_1.jsxs)("div", { style: { paddingTop: '20px' }, children: [tab === 'seo' && (0, jsx_runtime_1.jsx)(AuditPanel_js_1.AuditPanel, { embedded: true }), tab === 'freshness' && (0, jsx_runtime_1.jsx)(FreshnessPanel_js_1.FreshnessPanel, { embedded: true }), tab === 'insights' && (0, jsx_runtime_1.jsx)(InsightsTab, {})] }), (0, jsx_runtime_1.jsx)(CollectionLinks, {})] }));
72
+ }
73
+ function TabButton({ label, grade, active, onClick, }) {
74
+ return ((0, jsx_runtime_1.jsxs)("button", { onClick: onClick, style: {
75
+ background: 'transparent',
76
+ border: 'none',
77
+ borderBottom: active ? `2px solid ${ink.text}` : `2px solid transparent`,
78
+ marginBottom: '-1px',
79
+ padding: '10px 18px 10px 0',
80
+ marginRight: '24px',
81
+ fontFamily: mono,
82
+ fontSize: '11px',
83
+ letterSpacing: '0.15em',
84
+ textTransform: 'uppercase',
85
+ fontWeight: 700,
86
+ color: active ? ink.text : ink.textMuted,
87
+ cursor: 'pointer',
88
+ display: 'flex',
89
+ alignItems: 'center',
90
+ gap: '8px',
91
+ }, children: [label, grade && ((0, jsx_runtime_1.jsx)("span", { style: {
92
+ background: gradeColor[grade] ?? ink.borderStrong,
93
+ color: '#000',
94
+ padding: '2px 6px',
95
+ fontSize: '10px',
96
+ fontWeight: 800,
97
+ letterSpacing: 0,
98
+ }, children: grade }))] }));
99
+ }
100
+ function InsightsTab() {
101
+ const [data, setData] = (0, react_1.useState)(null);
102
+ const [error, setError] = (0, react_1.useState)(null);
103
+ const [loading, setLoading] = (0, react_1.useState)(true);
104
+ (0, react_1.useEffect)(() => {
105
+ let cancelled = false;
106
+ fetch('/api/ink/insights')
107
+ .then(async (r) => {
108
+ const d = await r.json();
109
+ if (!r.ok)
110
+ throw new Error(d.error ?? `Failed (${r.status})`);
111
+ return d;
112
+ })
113
+ .then((d) => {
114
+ if (!cancelled)
115
+ setData(d);
116
+ })
117
+ .catch((err) => {
118
+ if (!cancelled)
119
+ setError(err instanceof Error ? err.message : 'Unknown');
120
+ })
121
+ .finally(() => {
122
+ if (!cancelled)
123
+ setLoading(false);
124
+ });
125
+ return () => {
126
+ cancelled = true;
127
+ };
128
+ }, []);
129
+ if (loading)
130
+ return (0, jsx_runtime_1.jsx)("p", { style: { fontSize: '12px', color: ink.textMuted }, children: "Loading insights\u2026" });
131
+ if (error)
132
+ return (0, jsx_runtime_1.jsxs)("p", { style: { fontSize: '12px', color: '#f87171' }, children: ["ERROR > ", error] });
133
+ if (!data)
134
+ return null;
135
+ return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: '24px' }, children: [(0, jsx_runtime_1.jsx)(MoversSection, { label: "Top risers \u00B7 7d vs prior 7d", rows: data.topRisers, positive: true }), (0, jsx_runtime_1.jsx)(MoversSection, { label: "Top droppers \u00B7 7d vs prior 7d", rows: data.topDroppers, positive: false }), data.newThisPeriod && data.newThisPeriod.length > 0 && ((0, jsx_runtime_1.jsx)(NewSection, { rows: data.newThisPeriod })), (0, jsx_runtime_1.jsx)(ConversionSection, { checks: data.conversionChecks }), (0, jsx_runtime_1.jsx)(RecentInsightsSection, { insights: data.recentInsights })] }));
136
+ }
137
+ function MoversSection({ label, rows, positive }) {
138
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { style: { margin: '0 0 10px', fontSize: '10px', letterSpacing: '0.15em', textTransform: 'uppercase', color: ink.textSubtle, fontWeight: 700 }, children: label }), rows.length === 0 ? ((0, jsx_runtime_1.jsxs)("p", { style: { fontSize: '12px', color: ink.textSubtle, fontStyle: 'italic', margin: 0 }, children: ["No ", positive ? 'risers' : 'droppers', " above threshold."] })) : ((0, jsx_runtime_1.jsx)("div", { style: { background: '#1c1c1c', border: `1px solid ${ink.border}`, padding: '12px 14px' }, children: rows.map((r, i) => ((0, jsx_runtime_1.jsxs)("div", { style: {
139
+ display: 'grid',
140
+ gridTemplateColumns: '1fr 80px 80px',
141
+ gap: '12px',
142
+ alignItems: 'center',
143
+ padding: '6px 0',
144
+ borderBottom: i < rows.length - 1 ? `1px solid ${ink.border}` : 'none',
145
+ fontSize: '12px',
146
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { overflow: 'hidden' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { color: ink.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }, children: r.title || r.path }), (0, jsx_runtime_1.jsx)("div", { style: { color: ink.textSubtle, fontSize: '11px' }, children: r.path })] }), (0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'right', color: ink.text, fontFamily: mono }, children: [r.current.toLocaleString(), (0, jsx_runtime_1.jsx)("div", { style: { fontSize: '9px', color: ink.textSubtle, letterSpacing: '0.1em' }, children: "NOW" })] }), (0, jsx_runtime_1.jsxs)("div", { style: {
147
+ textAlign: 'right',
148
+ color: positive ? '#a3e635' : '#f87171',
149
+ fontFamily: mono,
150
+ fontWeight: 700,
151
+ }, children: [positive ? '▲' : '▼', " ", Math.abs(r.deltaPct).toFixed(0), "%", (0, jsx_runtime_1.jsxs)("div", { style: { fontSize: '9px', color: ink.textSubtle, letterSpacing: '0.1em', fontWeight: 400 }, children: ["vs ", r.previous.toLocaleString()] })] })] }, `${r.path}-${i}`))) }))] }));
152
+ }
153
+ function NewSection({ rows }) {
154
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { style: { margin: '0 0 10px', fontSize: '10px', letterSpacing: '0.15em', textTransform: 'uppercase', color: ink.textSubtle, fontWeight: 700 }, children: "New this period \u00B7 pages with no traffic prior 7d" }), (0, jsx_runtime_1.jsx)("div", { style: { background: '#1c1c1c', border: `1px solid ${ink.border}`, padding: '12px 14px' }, children: rows.map((r, i) => ((0, jsx_runtime_1.jsxs)("div", { style: {
155
+ display: 'grid',
156
+ gridTemplateColumns: '1fr 80px 60px',
157
+ gap: '12px',
158
+ alignItems: 'center',
159
+ padding: '6px 0',
160
+ borderBottom: i < rows.length - 1 ? `1px solid ${ink.border}` : 'none',
161
+ fontSize: '12px',
162
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { overflow: 'hidden' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { color: ink.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }, children: r.title || r.path }), (0, jsx_runtime_1.jsx)("div", { style: { color: ink.textSubtle, fontSize: '11px' }, children: r.path })] }), (0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'right', color: ink.text, fontFamily: mono }, children: [r.current.toLocaleString(), (0, jsx_runtime_1.jsx)("div", { style: { fontSize: '9px', color: ink.textSubtle, letterSpacing: '0.1em' }, children: "NOW" })] }), (0, jsx_runtime_1.jsx)("div", { style: { textAlign: 'right', color: '#a3e635', fontFamily: mono, fontWeight: 700, fontSize: '10px', letterSpacing: '0.1em' }, children: "NEW" })] }, `${r.path}-${i}`))) })] }));
163
+ }
164
+ function ConversionSection({ checks }) {
165
+ if (checks.length === 0) {
166
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { style: { margin: '0 0 10px', fontSize: '10px', letterSpacing: '0.15em', textTransform: 'uppercase', color: ink.textSubtle, fontWeight: 700 }, children: "Conversion measurement" }), (0, jsx_runtime_1.jsx)("p", { style: { fontSize: '12px', color: ink.textSubtle, fontStyle: 'italic', margin: 0 }, children: "No conversion events configured in your Onboarding Profile yet." })] }));
167
+ }
168
+ const broken = checks.filter((c) => c.observed === 0);
169
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { style: { margin: '0 0 10px', fontSize: '10px', letterSpacing: '0.15em', textTransform: 'uppercase', color: ink.textSubtle, fontWeight: 700 }, children: "Conversion measurement" }), (0, jsx_runtime_1.jsx)("div", { style: { background: '#1c1c1c', border: `1px solid ${ink.border}`, padding: '12px 14px' }, children: checks.map((c, i) => ((0, jsx_runtime_1.jsxs)("div", { style: {
170
+ display: 'grid',
171
+ gridTemplateColumns: '24px 1fr 80px',
172
+ gap: '12px',
173
+ alignItems: 'center',
174
+ padding: '6px 0',
175
+ borderBottom: i < checks.length - 1 ? `1px solid ${ink.border}` : 'none',
176
+ fontSize: '12px',
177
+ }, children: [(0, jsx_runtime_1.jsx)("span", { style: { color: c.observed > 0 ? '#a3e635' : '#f87171', fontWeight: 700 }, children: c.observed > 0 ? '✓' : '✗' }), (0, jsx_runtime_1.jsxs)("div", { style: { color: ink.text }, children: [(0, jsx_runtime_1.jsx)("code", { style: { fontFamily: mono, color: c.observed > 0 ? ink.text : ink.textMuted }, children: c.eventName }), c.observed === 0 && ((0, jsx_runtime_1.jsx)("div", { style: { color: ink.textSubtle, fontSize: '11px', marginTop: '2px' }, children: "Not seen in GA4 last 7d \u2014 check the event is firing or named differently." }))] }), (0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'right', color: ink.text, fontFamily: mono }, children: [c.observed.toLocaleString(), (0, jsx_runtime_1.jsx)("div", { style: { fontSize: '9px', color: ink.textSubtle, letterSpacing: '0.1em', fontWeight: 400 }, children: "7D EVENTS" })] })] }, `${c.eventName}-${i}`))) }), broken.length > 0 && ((0, jsx_runtime_1.jsxs)("p", { style: { margin: '10px 0 0', fontSize: '11px', color: '#fbbf24', lineHeight: 1.55 }, children: [broken.length, " configured conversion", broken.length === 1 ? '' : 's', " not measurable in GA4. Until these fire, INK can't tie audit findings to actual conversion impact."] }))] }));
178
+ }
179
+ function RecentInsightsSection({ insights }) {
180
+ if (insights.length === 0) {
181
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { style: { margin: '0 0 10px', fontSize: '10px', letterSpacing: '0.15em', textTransform: 'uppercase', color: ink.textSubtle, fontWeight: 700 }, children: "Recent audit findings" }), (0, jsx_runtime_1.jsx)("p", { style: { fontSize: '12px', color: ink.textSubtle, fontStyle: 'italic', margin: 0 }, children: "No pending audit findings. Run an audit to populate this." })] }));
182
+ }
183
+ const priColor = { high: '#f87171', medium: '#fbbf24', low: '#a3e635' };
184
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("p", { style: { margin: '0 0 10px', fontSize: '10px', letterSpacing: '0.15em', textTransform: 'uppercase', color: ink.textSubtle, fontWeight: 700 }, children: ["Recent audit findings \u00B7 ", insights.length, " pending"] }), (0, jsx_runtime_1.jsx)("div", { style: { background: '#1c1c1c', border: `1px solid ${ink.border}` }, children: insights.map((ins, i) => ((0, jsx_runtime_1.jsxs)("a", { href: `/admin/collections/ink-insights/${ins.id}`, style: {
185
+ display: 'grid',
186
+ gridTemplateColumns: '70px 1fr',
187
+ gap: '12px',
188
+ alignItems: 'flex-start',
189
+ padding: '10px 14px',
190
+ borderBottom: i < insights.length - 1 ? `1px solid ${ink.border}` : 'none',
191
+ fontSize: '12px',
192
+ textDecoration: 'none',
193
+ color: 'inherit',
194
+ }, children: [(0, jsx_runtime_1.jsx)("span", { style: {
195
+ fontSize: '9px',
196
+ color: priColor[ins.priority] ?? ink.textSubtle,
197
+ border: `1px solid ${priColor[ins.priority] ?? ink.textSubtle}`,
198
+ padding: '2px 6px',
199
+ letterSpacing: '0.08em',
200
+ fontWeight: 700,
201
+ textAlign: 'center',
202
+ textTransform: 'uppercase',
203
+ }, children: ins.priority }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { style: { color: ink.text, fontWeight: 700 }, children: ins.title }), ins.body && (0, jsx_runtime_1.jsx)("div", { style: { color: ink.textMuted, marginTop: '3px', lineHeight: 1.55 }, children: ins.body }), ins.pageUrl && (0, jsx_runtime_1.jsx)("div", { style: { color: ink.textSubtle, fontSize: '11px', marginTop: '3px' }, children: ins.pageUrl })] })] }, ins.id))) })] }));
204
+ }
205
+ function CollectionLinks() {
206
+ const links = [
207
+ { label: 'Audits', href: '/admin/collections/ink-audits' },
208
+ { label: 'Insights', href: '/admin/collections/ink-insights' },
209
+ { label: 'Actions', href: '/admin/collections/ink-actions' },
210
+ { label: 'Profile', href: '/admin/collections/ink-onboarding-profile' },
211
+ ];
212
+ return ((0, jsx_runtime_1.jsx)("div", { style: {
213
+ marginTop: '28px',
214
+ paddingTop: '14px',
215
+ borderTop: `1px solid ${ink.border}`,
216
+ display: 'flex',
217
+ gap: '20px',
218
+ flexWrap: 'wrap',
219
+ }, children: links.map((l) => ((0, jsx_runtime_1.jsxs)("a", { href: l.href, style: {
220
+ fontSize: '10px',
221
+ letterSpacing: '0.15em',
222
+ textTransform: 'uppercase',
223
+ color: ink.textMuted,
224
+ fontWeight: 700,
225
+ textDecoration: 'none',
226
+ fontFamily: mono,
227
+ }, children: ["\u2192 ", l.label] }, l.href))) }));
228
+ }
229
+ //# sourceMappingURL=AuditsPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditsPanel.js","sourceRoot":"","sources":["../../src/components/AuditsPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function DigestPanel(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=DigestPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DigestPanel.d.ts","sourceRoot":"","sources":["../../src/components/DigestPanel.tsx"],"names":[],"mappings":"AAqCA,wBAAgB,WAAW,4CAia1B"}
@@ -0,0 +1,320 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.DigestPanel = DigestPanel;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const ink = {
8
+ bg: '#0a0a0a',
9
+ surface: '#141414',
10
+ surfaceElev: '#1c1c1c',
11
+ border: '#262626',
12
+ borderStrong: '#3a3a3a',
13
+ text: '#fafafa',
14
+ textMuted: '#a3a3a3',
15
+ textSubtle: '#737373',
16
+ accent: '#fafafa',
17
+ accentText: '#0a0a0a',
18
+ success: '#a3e635',
19
+ danger: '#f87171',
20
+ };
21
+ const mono = "'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
22
+ function DigestPanel() {
23
+ const [mode, setMode] = (0, react_1.useState)('idle');
24
+ const [error, setError] = (0, react_1.useState)(null);
25
+ const [result, setResult] = (0, react_1.useState)(null);
26
+ const [lastPreview, setLastPreview] = (0, react_1.useState)(null);
27
+ const [previewVisible, setPreviewVisible] = (0, react_1.useState)(false);
28
+ const [preflight, setPreflight] = (0, react_1.useState)(null);
29
+ const [dots, setDots] = (0, react_1.useState)('');
30
+ const [phase, setPhase] = (0, react_1.useState)('');
31
+ const [profileId, setProfileId] = (0, react_1.useState)(null);
32
+ const [autoSend, setAutoSend] = (0, react_1.useState)(true);
33
+ const [cadence, setCadence] = (0, react_1.useState)('weekly');
34
+ const [lastSentAt, setLastSentAt] = (0, react_1.useState)(null);
35
+ const [savingToggle, setSavingToggle] = (0, react_1.useState)(false);
36
+ const [isSuperAdmin, setIsSuperAdmin] = (0, react_1.useState)(true);
37
+ const [adminCheckDone, setAdminCheckDone] = (0, react_1.useState)(false);
38
+ const [adminContacts, setAdminContacts] = (0, react_1.useState)([]);
39
+ (0, react_1.useEffect)(() => {
40
+ if (mode === 'idle') {
41
+ setDots('');
42
+ setPhase('');
43
+ return;
44
+ }
45
+ let i = 0;
46
+ const dotsInterval = setInterval(() => {
47
+ i = (i + 1) % 4;
48
+ setDots('.'.repeat(i));
49
+ }, 350);
50
+ const start = Date.now();
51
+ const phaseInterval = setInterval(() => {
52
+ const elapsed = (Date.now() - start) / 1000;
53
+ if (mode === 'previewing') {
54
+ if (elapsed < 4)
55
+ setPhase('Gathering data');
56
+ else if (elapsed < 25)
57
+ setPhase('AI is writing in your brand voice');
58
+ else
59
+ setPhase('Almost there');
60
+ }
61
+ else if (mode === 'sending') {
62
+ setPhase(lastPreview ? 'Reusing preview · delivering to Resend' : 'Writing and delivering');
63
+ }
64
+ }, 250);
65
+ return () => {
66
+ clearInterval(dotsInterval);
67
+ clearInterval(phaseInterval);
68
+ };
69
+ }, [mode, lastPreview]);
70
+ (0, react_1.useEffect)(() => {
71
+ let cancelled = false;
72
+ Promise.all([
73
+ fetch('/api/users/me').then((r) => (r.ok ? r.json() : null)).catch(() => null),
74
+ fetch('/api/ink/config').then((r) => (r.ok ? r.json() : null)).catch(() => null),
75
+ ]).then(([me, cfg]) => {
76
+ if (cancelled)
77
+ return;
78
+ const email = me?.user?.email;
79
+ const admins = cfg?.superAdminEmails ?? [];
80
+ setAdminContacts(admins);
81
+ setIsSuperAdmin(admins.length === 0 ? true : Boolean(email && admins.includes(email)));
82
+ setAdminCheckDone(true);
83
+ });
84
+ fetch('/api/ink/digest-preflight')
85
+ .then((r) => (r.ok ? r.json() : null))
86
+ .then((data) => {
87
+ if (!cancelled && data)
88
+ setPreflight(data);
89
+ })
90
+ .catch(() => { });
91
+ fetch('/api/ink-onboarding-profile?limit=1&depth=0')
92
+ .then((r) => (r.ok ? r.json() : null))
93
+ .then((data) => {
94
+ if (cancelled)
95
+ return;
96
+ const doc = data?.docs?.[0];
97
+ if (!doc)
98
+ return;
99
+ const cached = doc.lastDigestPreview;
100
+ if (cached && cached.subject && cached.html)
101
+ setLastPreview(cached);
102
+ setProfileId(String(doc.id));
103
+ if (typeof doc.digestEnabled === 'boolean')
104
+ setAutoSend(doc.digestEnabled);
105
+ if (typeof doc.cadence === 'string')
106
+ setCadence(doc.cadence);
107
+ if (typeof doc.lastDigestSentAt === 'string')
108
+ setLastSentAt(doc.lastDigestSentAt);
109
+ })
110
+ .catch(() => { });
111
+ return () => {
112
+ cancelled = true;
113
+ };
114
+ }, []);
115
+ async function trigger(dryRun) {
116
+ setMode(dryRun ? 'previewing' : 'sending');
117
+ setError(null);
118
+ try {
119
+ const reuse = !dryRun && lastPreview ? lastPreview : null;
120
+ const body = {
121
+ dryRun,
122
+ ...(reuse ? { preRendered: reuse } : {}),
123
+ };
124
+ const res = await fetch('/api/ink/send-digest', {
125
+ method: 'POST',
126
+ headers: { 'Content-Type': 'application/json' },
127
+ body: JSON.stringify(body),
128
+ });
129
+ const data = (await res.json());
130
+ if (!res.ok)
131
+ throw new Error(data.error ?? 'Digest failed');
132
+ setResult(data);
133
+ if (dryRun) {
134
+ setLastPreview({
135
+ subject: data.subject,
136
+ html: data.html,
137
+ text: data.text,
138
+ topActions: data.topActions,
139
+ generatedAt: new Date().toISOString(),
140
+ });
141
+ setPreviewVisible(true);
142
+ }
143
+ else {
144
+ // After a send, clear cached preview so the next preview is fresh
145
+ setLastPreview(null);
146
+ setLastSentAt(new Date().toISOString());
147
+ }
148
+ }
149
+ catch (err) {
150
+ setError(err instanceof Error ? err.message : 'Unknown error');
151
+ }
152
+ finally {
153
+ setMode('idle');
154
+ }
155
+ }
156
+ const busy = mode !== 'idle';
157
+ const sendBlocked = Boolean(preflight && !preflight.ok);
158
+ async function toggleAutoSend(next) {
159
+ if (!profileId)
160
+ return;
161
+ setSavingToggle(true);
162
+ try {
163
+ const res = await fetch(`/api/ink-onboarding-profile/${profileId}`, {
164
+ method: 'PATCH',
165
+ headers: { 'Content-Type': 'application/json' },
166
+ body: JSON.stringify({ digestEnabled: next }),
167
+ });
168
+ if (res.ok)
169
+ setAutoSend(next);
170
+ }
171
+ catch {
172
+ // ignore
173
+ }
174
+ finally {
175
+ setSavingToggle(false);
176
+ }
177
+ }
178
+ function nextScheduled() {
179
+ if (!autoSend)
180
+ return null;
181
+ const days = cadence === 'fortnightly' ? 14 : cadence === 'monthly' ? 28 : 7;
182
+ const baseline = lastSentAt ? new Date(lastSentAt).getTime() : Date.now();
183
+ const due = new Date(baseline + days * 24 * 60 * 60 * 1000);
184
+ return due.toLocaleDateString(undefined, { weekday: 'short', month: 'short', day: 'numeric' });
185
+ }
186
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
187
+ background: ink.bg,
188
+ color: ink.text,
189
+ fontFamily: mono,
190
+ padding: '24px',
191
+ border: `1px solid ${ink.border}`,
192
+ maxWidth: '780px',
193
+ margin: '24px 0',
194
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
195
+ display: 'flex',
196
+ justifyContent: 'space-between',
197
+ alignItems: 'center',
198
+ borderBottom: `1px solid ${ink.border}`,
199
+ paddingBottom: '12px',
200
+ }, children: (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'baseline', gap: '12px' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { fontSize: '11px', letterSpacing: '0.15em', color: ink.textMuted, fontWeight: 700 }, children: "INK" }), (0, jsx_runtime_1.jsx)("span", { style: { color: ink.textSubtle }, children: "/" }), (0, jsx_runtime_1.jsx)("span", { style: { fontSize: '11px', letterSpacing: '0.1em', color: ink.text, textTransform: 'uppercase' }, children: "Weekly digest" })] }) }), (0, jsx_runtime_1.jsx)("p", { style: { marginTop: '18px', marginBottom: '18px', fontSize: '13px', color: ink.textMuted, lineHeight: 1.55 }, children: "Assembles last 7 days of traffic, audits, completed actions and pending insights into a brand-voice email. Preview first to see the rendered HTML; Send delivers to the recipients on your onboarding profile." }), preflight && (0, jsx_runtime_1.jsx)(PreflightStatus, { preflight: preflight }), (0, jsx_runtime_1.jsxs)("div", { style: {
201
+ marginTop: preflight ? '14px' : 0,
202
+ background: ink.surface,
203
+ border: `1px solid ${ink.border}`,
204
+ padding: '14px 16px',
205
+ display: 'flex',
206
+ gap: '18px',
207
+ alignItems: 'center',
208
+ flexWrap: 'wrap',
209
+ }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => toggleAutoSend(!autoSend), disabled: savingToggle || !profileId, style: {
210
+ background: autoSend ? ink.success : 'transparent',
211
+ color: autoSend ? ink.bg : ink.textMuted,
212
+ border: `1px solid ${autoSend ? ink.success : ink.borderStrong}`,
213
+ padding: '6px 14px',
214
+ fontSize: '10px',
215
+ fontWeight: 700,
216
+ letterSpacing: '0.15em',
217
+ textTransform: 'uppercase',
218
+ fontFamily: mono,
219
+ cursor: savingToggle || !profileId ? 'not-allowed' : 'pointer',
220
+ }, children: autoSend ? '● Auto-send on' : '○ Auto-send off' }), (0, jsx_runtime_1.jsxs)("div", { style: { fontSize: '11px', color: ink.textMuted, lineHeight: 1.6 }, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { style: { color: ink.textSubtle, letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 700 }, children: "Cadence" }), ' ', (0, jsx_runtime_1.jsx)("span", { style: { color: ink.text }, children: cadence })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { style: { color: ink.textSubtle, letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 700 }, children: "Last sent" }), ' ', (0, jsx_runtime_1.jsx)("span", { style: { color: ink.text }, children: lastSentAt ? timeAgo(lastSentAt) : 'never' })] }), autoSend && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { style: { color: ink.textSubtle, letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 700 }, children: "Next scheduled" }), ' ', (0, jsx_runtime_1.jsx)("span", { style: { color: ink.text }, children: nextScheduled() ?? '—' })] }))] })] }), adminCheckDone && !isSuperAdmin && ((0, jsx_runtime_1.jsxs)("div", { style: {
221
+ marginTop: '18px',
222
+ background: ink.surface,
223
+ border: `1px solid ${ink.border}`,
224
+ padding: '14px 16px',
225
+ fontSize: '12px',
226
+ color: ink.textMuted,
227
+ lineHeight: 1.6,
228
+ }, children: [(0, jsx_runtime_1.jsxs)("p", { style: { margin: 0 }, children: [(0, jsx_runtime_1.jsx)("span", { style: { color: ink.text, fontWeight: 700 }, children: "Read-only view." }), ' ', "You can see digest status and the last preview, but only the INK administrator can regenerate or send manually. Auto-send still runs on schedule when enabled."] }), adminContacts.length > 0 && ((0, jsx_runtime_1.jsxs)("p", { style: { margin: '8px 0 0', fontSize: '11px', color: ink.textSubtle }, children: ["For changes contact:", ' ', adminContacts.map((e, i) => ((0, jsx_runtime_1.jsxs)("span", { children: [i > 0 && ', ', (0, jsx_runtime_1.jsx)("a", { href: `mailto:${e}`, style: { color: ink.text, textDecoration: 'none' }, children: e })] }, e)))] }))] })), isSuperAdmin && ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: '12px', alignItems: 'center', flexWrap: 'wrap', marginTop: '18px' }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => trigger(true), disabled: busy, style: {
229
+ background: busy ? ink.borderStrong : 'transparent',
230
+ color: busy ? ink.textSubtle : ink.text,
231
+ border: `1px solid ${busy ? ink.borderStrong : ink.text}`,
232
+ padding: '9px 18px',
233
+ cursor: busy ? 'not-allowed' : 'pointer',
234
+ fontFamily: mono,
235
+ fontSize: '11px',
236
+ fontWeight: 700,
237
+ textTransform: 'uppercase',
238
+ letterSpacing: '0.08em',
239
+ }, children: mode === 'previewing' ? `Generating${dots}` : 'Preview digest' }), (0, jsx_runtime_1.jsx)("button", { onClick: () => trigger(false), disabled: busy || sendBlocked, title: sendBlocked ? 'Preflight checks failed — see status above' : undefined, style: {
240
+ background: busy || sendBlocked ? ink.borderStrong : ink.accent,
241
+ color: busy || sendBlocked ? ink.textSubtle : ink.accentText,
242
+ border: 'none',
243
+ padding: '10px 20px',
244
+ cursor: busy || sendBlocked ? 'not-allowed' : 'pointer',
245
+ fontFamily: mono,
246
+ fontSize: '12px',
247
+ fontWeight: 700,
248
+ textTransform: 'uppercase',
249
+ letterSpacing: '0.08em',
250
+ }, children: mode === 'sending'
251
+ ? `Sending${dots}`
252
+ : sendBlocked
253
+ ? 'Sending blocked'
254
+ : lastPreview
255
+ ? 'Send this preview'
256
+ : 'Send digest now' }), lastPreview?.generatedAt && ((0, jsx_runtime_1.jsxs)("span", { style: { fontSize: '11px', color: ink.textSubtle, letterSpacing: '0.05em' }, children: ["preview cached \u00B7 generated ", timeAgo(lastPreview.generatedAt)] }))] })), busy && phase && ((0, jsx_runtime_1.jsxs)("div", { style: {
257
+ marginTop: '14px',
258
+ display: 'flex',
259
+ alignItems: 'center',
260
+ gap: '12px',
261
+ fontSize: '12px',
262
+ color: ink.textMuted,
263
+ }, children: [(0, jsx_runtime_1.jsx)(ProgressBar, {}), (0, jsx_runtime_1.jsxs)("span", { children: [phase, dots] })] })), error && ((0, jsx_runtime_1.jsxs)("p", { style: { color: ink.danger, fontSize: '12px', marginTop: '16px' }, children: ["ERROR > ", error] })), result && ((0, jsx_runtime_1.jsxs)("div", { style: { marginTop: '20px', background: ink.surface, border: `1px solid ${ink.border}`, padding: '16px 18px' }, children: [(0, jsx_runtime_1.jsx)("p", { style: { margin: '0 0 6px', fontSize: '10px', letterSpacing: '0.15em', textTransform: 'uppercase', color: ink.textSubtle, fontWeight: 700 }, children: "Subject" }), (0, jsx_runtime_1.jsx)("p", { style: { margin: '0 0 14px', fontSize: '14px', color: ink.text, fontWeight: 700 }, children: result.subject }), result.topActions.length > 0 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("p", { style: { margin: '0 0 6px', fontSize: '10px', letterSpacing: '0.15em', textTransform: 'uppercase', color: ink.textSubtle, fontWeight: 700 }, children: "Top actions" }), (0, jsx_runtime_1.jsx)("ol", { style: { margin: 0, padding: 0, listStyle: 'none' }, children: result.topActions.map((a, i) => ((0, jsx_runtime_1.jsxs)("li", { style: { fontSize: '12px', color: ink.text, lineHeight: 1.55, display: 'flex', gap: '10px', padding: '2px 0' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { color: ink.textSubtle, minWidth: '20px' }, children: String(i + 1).padStart(2, '0') }), (0, jsx_runtime_1.jsx)("span", { children: a })] }, i))) })] })), (0, jsx_runtime_1.jsxs)("div", { style: { marginTop: '14px', display: 'flex', gap: '14px', alignItems: 'center', flexWrap: 'wrap' }, children: [result.dryRun ? ((0, jsx_runtime_1.jsx)("span", { style: { fontSize: '10px', color: ink.textSubtle, letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 700 }, children: "Preview only \u00B7 not sent" })) : ((0, jsx_runtime_1.jsxs)("span", { style: { fontSize: '10px', color: ink.success, letterSpacing: '0.1em', textTransform: 'uppercase', fontWeight: 700 }, children: ["\u2713 Sent to ", (result.sentTo ?? []).length, " recipient", (result.sentTo?.length ?? 0) === 1 ? '' : 's', result.reusedPreview && ((0, jsx_runtime_1.jsx)("span", { style: { color: ink.textSubtle, marginLeft: '8px', fontWeight: 500 }, children: "\u00B7 reused preview (no AI call)" }))] })), (0, jsx_runtime_1.jsx)("button", { onClick: () => setPreviewVisible((v) => !v), style: {
264
+ background: 'transparent',
265
+ color: ink.textMuted,
266
+ border: 'none',
267
+ fontSize: '10px',
268
+ letterSpacing: '0.15em',
269
+ textTransform: 'uppercase',
270
+ fontWeight: 700,
271
+ cursor: 'pointer',
272
+ fontFamily: mono,
273
+ }, children: previewVisible ? 'Hide preview' : 'Show preview' })] }), previewVisible && ((0, jsx_runtime_1.jsx)("iframe", { title: "Digest preview", srcDoc: result.html, style: {
274
+ width: '100%',
275
+ height: '600px',
276
+ border: `1px solid ${ink.border}`,
277
+ marginTop: '14px',
278
+ background: '#0a0a0a',
279
+ } }))] }))] }));
280
+ }
281
+ function ProgressBar() {
282
+ return ((0, jsx_runtime_1.jsxs)("svg", { width: "120", height: "6", viewBox: "0 0 120 6", style: { flexShrink: 0 }, children: [(0, jsx_runtime_1.jsx)("rect", { x: "0", y: "2", width: "120", height: "2", fill: ink.border }), (0, jsx_runtime_1.jsx)("rect", { x: "0", y: "0", width: "30", height: "6", fill: ink.success, children: (0, jsx_runtime_1.jsx)("animate", { attributeName: "x", values: "-30;120", dur: "1.4s", repeatCount: "indefinite" }) })] }));
283
+ }
284
+ function timeAgo(iso) {
285
+ const diff = Date.now() - new Date(iso).getTime();
286
+ if (Number.isNaN(diff) || diff < 0)
287
+ return 'just now';
288
+ const s = Math.floor(diff / 1000);
289
+ if (s < 60)
290
+ return 'just now';
291
+ const m = Math.floor(s / 60);
292
+ if (m < 60)
293
+ return `${m}m ago`;
294
+ const h = Math.floor(m / 60);
295
+ if (h < 24)
296
+ return `${h}h ago`;
297
+ const d = Math.floor(h / 24);
298
+ return `${d}d ago`;
299
+ }
300
+ function PreflightStatus({ preflight }) {
301
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
302
+ background: preflight.ok ? ink.surface : '#1a1208',
303
+ border: `1px solid ${preflight.ok ? ink.border : '#7c2d12'}`,
304
+ padding: '12px 16px',
305
+ marginBottom: '4px',
306
+ }, children: [(0, jsx_runtime_1.jsx)("p", { style: {
307
+ margin: '0 0 8px',
308
+ fontSize: '10px',
309
+ letterSpacing: '0.15em',
310
+ textTransform: 'uppercase',
311
+ color: preflight.ok ? ink.textSubtle : '#fbbf24',
312
+ fontWeight: 700,
313
+ }, children: preflight.ok ? 'Preflight · ready to send' : 'Preflight · attention needed' }), (0, jsx_runtime_1.jsx)("ul", { style: { margin: 0, padding: 0, listStyle: 'none', display: 'flex', flexDirection: 'column', gap: '4px' }, children: preflight.checks.map((c, i) => ((0, jsx_runtime_1.jsxs)("li", { style: {
314
+ display: 'flex',
315
+ gap: '10px',
316
+ fontSize: '12px',
317
+ color: c.ok ? ink.textMuted : ink.text,
318
+ }, children: [(0, jsx_runtime_1.jsx)("span", { style: { color: c.ok ? ink.success : ink.danger, minWidth: '14px' }, children: c.ok ? '✓' : '✗' }), (0, jsx_runtime_1.jsxs)("span", { style: { flex: 1 }, children: [(0, jsx_runtime_1.jsx)("span", { style: { color: ink.text }, children: c.label }), c.detail && (0, jsx_runtime_1.jsxs)("span", { style: { color: ink.textSubtle, marginLeft: '8px' }, children: ["\u00B7 ", c.detail] })] })] }, i))) })] }));
319
+ }
320
+ //# sourceMappingURL=DigestPanel.js.map