chore(audit-drain): rip out next-intl, RTL lint, sweeps, polish
Drain the long-tail audit queue captured in alpha-uat-master.md.
- next-intl ripped out (zero useTranslations callers ever existed):
package.json, next.config.ts plugin wrap, src/i18n/, messages/, and
the layout NextIntlClientProvider all gone; <html lang="en"> hardcoded.
- RTL lint nudge added: warn-only no-restricted-syntax on physical
Tailwind utilities (ml-/mr-/pl-/pr-/text-left/text-right/border-l/
border-r/rounded-l-/rounded-r-) inside JSX className literals.
Existing ~1,000 sites grandfathered; new code trends toward logical.
- Icon-only button accessibility lint: jsx-a11y/control-has-associated-
label enabled at warn; 4 empty <th>/<td> action placeholders gain
sr-only labels.
- Currency: SUPPORTED_CURRENCIES drops the hardcoded English labels;
new currencyLabel(code, locale?) helper resolves via Intl.DisplayNames.
CurrencySelect + settings-manager migrated.
- Date locale sweep: 7 surfaces flip from toLocaleString('en-GB'|'en-US')
to toLocaleString(undefined, ...) so dates honour runtime locale.
- Dialog/Sheet width: 10 document/EOI/entity-form dialogs gain a
lg:max-w-4xl or lg:max-w-5xl step so wide desktops get breathing room.
- PaymentsSection collapsed-bar: slim one-line bar showing
"Payments - Not received yet" or "Payments - \$X received - N payments
- Expand"; per-interest collapse state persists in localStorage; the
RecordPayment flow auto-expands.
- muted-foreground opacity sweep: 10 text-bearing
text-muted-foreground/{60,70,80} hits dropped to plain
text-muted-foreground for AA contrast on muted bg. Icon-only
(aria-hidden) opacity hits left as-is.
- Micro-type bump: text-[10px] and text-[11px] -> text-xs (12px)
across 87 files in src/components + src/app. Pure mechanical sweep.
- Audit-doc cleanup: alpha-uat-master.md stale 2026-05-25 summary
rewritten with cumulative state through today. Items genuinely still
open are now a short long-tail list.
- New docs/marketing-site-followups.md: Umami Phase 4a/3/5, email
pixel E2E verification, and website-cutover work parked here so
they don't get lost in the CRM audit doc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -167,7 +167,7 @@ export function EmbeddedSigningCard() {
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
<p className="mt-1 text-[11px] opacity-70">{result.at.toLocaleTimeString()}</p>
|
||||
<p className="mt-1 text-xs opacity-70">{result.at.toLocaleTimeString()}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -204,7 +204,7 @@ export function EmbeddedSigningCard() {
|
||||
tracking which slot the signer is in.
|
||||
</p>
|
||||
<p className="mt-1 text-muted-foreground">Minimum Next.js example:</p>
|
||||
<pre className="mt-1 overflow-x-auto rounded bg-muted p-2 font-mono text-[11px]">
|
||||
<pre className="mt-1 overflow-x-auto rounded bg-muted p-2 font-mono text-xs">
|
||||
{`// app/sign/[role]/[token]/page.tsx
|
||||
export default function SignPage({ params }) {
|
||||
const documenseUrl = \`\${env.DOCUMENSO_URL}/sign/\${params.token}\`;
|
||||
|
||||
@@ -179,7 +179,7 @@ export function TemplateSyncButton() {
|
||||
<CheckCircle2 className="size-4" />{' '}
|
||||
{lastResult.title || `Template #${lastResult.templateId}`}
|
||||
</div>
|
||||
<span className="text-[11px] font-normal text-muted-foreground">
|
||||
<span className="text-xs font-normal text-muted-foreground">
|
||||
Last synced {formatRelative(lastResult.syncedAt)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -202,11 +202,11 @@ export function TemplateSyncButton() {
|
||||
</>
|
||||
)}
|
||||
{r.mappedSettingKey ? (
|
||||
<span className="ml-auto rounded bg-emerald-100 px-1.5 py-0.5 text-[10px] font-medium text-emerald-800 dark:bg-emerald-950 dark:text-emerald-300">
|
||||
<span className="ml-auto rounded bg-emerald-100 px-1.5 py-0.5 text-xs font-medium text-emerald-800 dark:bg-emerald-950 dark:text-emerald-300">
|
||||
→ {r.mappedSettingKey}
|
||||
</span>
|
||||
) : (
|
||||
<span className="ml-auto rounded bg-amber-100 px-1.5 py-0.5 text-[10px] font-medium text-amber-800 dark:bg-amber-950 dark:text-amber-300">
|
||||
<span className="ml-auto rounded bg-amber-100 px-1.5 py-0.5 text-xs font-medium text-amber-800 dark:bg-amber-950 dark:text-amber-300">
|
||||
no slot match
|
||||
</span>
|
||||
)}
|
||||
@@ -216,13 +216,13 @@ export function TemplateSyncButton() {
|
||||
{lastResult.templateMeta && (
|
||||
<div className="pt-1.5 rounded-md bg-muted/60 px-2 py-1.5">
|
||||
<div className="font-medium text-muted-foreground">Template-level settings</div>
|
||||
<p className="text-[11px] text-muted-foreground">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Read from the template itself on Documenso. These values are bound to the
|
||||
template, so every envelope generated from it inherits them -{' '}
|
||||
<code>/template/use</code> does <strong>not</strong> accept overrides for these.
|
||||
Change them in Documenso's template editor.
|
||||
</p>
|
||||
<ul className="mt-1 space-y-0.5 text-[11px]">
|
||||
<ul className="mt-1 space-y-0.5 text-xs">
|
||||
<li>
|
||||
<span className="text-muted-foreground">Signing order:</span>{' '}
|
||||
<span className="font-mono">
|
||||
@@ -235,7 +235,7 @@ export function TemplateSyncButton() {
|
||||
{lastResult.templateMeta.distributionMethod ?? 'unset'}
|
||||
</span>
|
||||
{lastResult.templateMeta.distributionMethod === 'EMAIL' && (
|
||||
<span className="ml-1 rounded bg-amber-100 px-1.5 py-0.5 text-[10px] font-medium text-amber-900 dark:bg-amber-950 dark:text-amber-200">
|
||||
<span className="ml-1 rounded bg-amber-100 px-1.5 py-0.5 text-xs font-medium text-amber-900 dark:bg-amber-950 dark:text-amber-200">
|
||||
⚠️ Documenso will email recipients directly - the CRM's branded email
|
||||
is in addition. Set to NONE on the template to let the CRM be the sole
|
||||
sender.
|
||||
@@ -273,7 +273,7 @@ export function TemplateSyncButton() {
|
||||
{lastResult.matchedFields.map((f) => (
|
||||
<span
|
||||
key={f.fieldId}
|
||||
className="rounded bg-emerald-100 px-1.5 py-0.5 font-mono text-[10px] text-emerald-900 dark:bg-emerald-950 dark:text-emerald-200"
|
||||
className="rounded bg-emerald-100 px-1.5 py-0.5 font-mono text-xs text-emerald-900 dark:bg-emerald-950 dark:text-emerald-200"
|
||||
>
|
||||
{f.label} → #{f.fieldId}
|
||||
</span>
|
||||
@@ -288,7 +288,7 @@ export function TemplateSyncButton() {
|
||||
⚠️ Template fields the CRM doesn't recognize (
|
||||
{lastResult.unmatchedTemplateFields.length})
|
||||
</div>
|
||||
<p className="text-[11px] text-muted-foreground">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
These won't be filled. Rename them in the Documenso template editor to match
|
||||
a CRM-expected label (Name, Email, Address, Yacht Name, Length, Width, Draft,
|
||||
Berth Number, Lease_10, Purchase), or ignore if they're signature/date fields
|
||||
@@ -298,7 +298,7 @@ export function TemplateSyncButton() {
|
||||
{lastResult.unmatchedTemplateFields.map((f) => (
|
||||
<span
|
||||
key={f.fieldId}
|
||||
className="rounded bg-amber-100 px-1.5 py-0.5 font-mono text-[10px] text-amber-900 dark:bg-amber-950 dark:text-amber-200"
|
||||
className="rounded bg-amber-100 px-1.5 py-0.5 font-mono text-xs text-amber-900 dark:bg-amber-950 dark:text-amber-200"
|
||||
>
|
||||
{f.label} → #{f.fieldId}
|
||||
</span>
|
||||
@@ -312,7 +312,7 @@ export function TemplateSyncButton() {
|
||||
<div className="font-medium text-foreground">
|
||||
PDF AcroForm fields (the <code>formValues</code> path)
|
||||
</div>
|
||||
<p className="pt-0.5 text-[11px] text-muted-foreground">
|
||||
<p className="pt-0.5 text-xs text-muted-foreground">
|
||||
These are the fillable fields actually in the PDF binary on Documenso. The CRM
|
||||
fills them by name at send time - this is the same mechanism the prod v1 server
|
||||
uses.
|
||||
@@ -320,11 +320,11 @@ export function TemplateSyncButton() {
|
||||
{lastResult.acroForm.map((report) => (
|
||||
<div key={report.envelopeItemId} className="mt-1.5 space-y-1">
|
||||
{report.error ? (
|
||||
<div className="rounded bg-destructive/10 px-2 py-1 text-[11px] text-destructive">
|
||||
<div className="rounded bg-destructive/10 px-2 py-1 text-xs text-destructive">
|
||||
Couldn't inspect this PDF: {report.error}
|
||||
</div>
|
||||
) : report.fields.length === 0 ? (
|
||||
<div className="rounded bg-amber-100 px-2 py-1 text-[11px] text-amber-900 dark:bg-amber-950 dark:text-amber-200">
|
||||
<div className="rounded bg-amber-100 px-2 py-1 text-xs text-amber-900 dark:bg-amber-950 dark:text-amber-200">
|
||||
⚠️ This PDF has no AcroForm fields. The CRM's <code>formValues</code>{' '}
|
||||
path will fill nothing. Re-export your PDF with form fields enabled, or
|
||||
place overlays inside Documenso's editor and use{' '}
|
||||
@@ -341,7 +341,7 @@ export function TemplateSyncButton() {
|
||||
{report.matchedFieldNames.map((n) => (
|
||||
<span
|
||||
key={n}
|
||||
className="rounded bg-emerald-100 px-1.5 py-0.5 font-mono text-[10px] text-emerald-900 dark:bg-emerald-950 dark:text-emerald-200"
|
||||
className="rounded bg-emerald-100 px-1.5 py-0.5 font-mono text-xs text-emerald-900 dark:bg-emerald-950 dark:text-emerald-200"
|
||||
>
|
||||
{n}
|
||||
</span>
|
||||
@@ -354,7 +354,7 @@ export function TemplateSyncButton() {
|
||||
<div className="font-medium text-amber-700 dark:text-amber-400">
|
||||
⚠️ CRM tokens missing from the PDF ({report.missingFieldNames.length})
|
||||
</div>
|
||||
<p className="text-[11px] text-muted-foreground">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
These exact names need AcroForm text/checkbox fields in the PDF, or
|
||||
they'll be dropped at send time.
|
||||
</p>
|
||||
@@ -362,7 +362,7 @@ export function TemplateSyncButton() {
|
||||
{report.missingFieldNames.map((n) => (
|
||||
<span
|
||||
key={n}
|
||||
className="rounded bg-amber-100 px-1.5 py-0.5 font-mono text-[10px] text-amber-900 dark:bg-amber-950 dark:text-amber-200"
|
||||
className="rounded bg-amber-100 px-1.5 py-0.5 font-mono text-xs text-amber-900 dark:bg-amber-950 dark:text-amber-200"
|
||||
>
|
||||
{n}
|
||||
</span>
|
||||
@@ -375,7 +375,7 @@ export function TemplateSyncButton() {
|
||||
<div className="font-medium text-muted-foreground">
|
||||
PDF fields the CRM has no token for ({report.extraFieldNames.length})
|
||||
</div>
|
||||
<p className="text-[11px] text-muted-foreground">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Usually signature blocks or other fields the recipient fills in
|
||||
directly. Safe to ignore.
|
||||
</p>
|
||||
@@ -383,7 +383,7 @@ export function TemplateSyncButton() {
|
||||
{report.extraFieldNames.map((n) => (
|
||||
<span
|
||||
key={n}
|
||||
className="rounded bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground"
|
||||
className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs text-muted-foreground"
|
||||
>
|
||||
{n}
|
||||
</span>
|
||||
@@ -404,7 +404,7 @@ export function TemplateSyncButton() {
|
||||
CRM data points not in <code>prefillFields</code> (
|
||||
{lastResult.missingFromTemplate.length})
|
||||
</div>
|
||||
<p className="text-[11px] text-muted-foreground">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
These would also be available as <code>prefillFields</code> if you added matching
|
||||
overlays inside Documenso's template editor.
|
||||
</p>
|
||||
@@ -412,7 +412,7 @@ export function TemplateSyncButton() {
|
||||
{lastResult.missingFromTemplate.map((label) => (
|
||||
<span
|
||||
key={label}
|
||||
className="rounded bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground"
|
||||
className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs text-muted-foreground"
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user