feat(export): add branding footer to all 5 export formats and PDF spinner

- Add "Generated with ResolutionFlow — https://resolutionflow.com" footer
  to markdown, text, HTML, PSA formats (both troubleshooting and procedural
  variants — 8 generators total)
- Fix PDF @page CSS: "Powered by ResolutionFlow" now appears on every PDF,
  not just for users with a custom logo (removed the has_custom_logo conditional)
- Add Loader2 spinner icon to PDF download button in ExportPreviewModal
  when pdfLoading is true, replacing the static Download icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 20:09:26 +00:00
parent 12a373a2a2
commit 967a2b2c59
3 changed files with 42 additions and 14 deletions

View File

@@ -299,6 +299,10 @@ def generate_markdown_export(session: Session, options: SessionExport, supportin
lines.append(next_steps.strip())
lines.append("")
# Branding footer
lines.append("---")
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
return "\n".join(lines)
@@ -408,6 +412,11 @@ def generate_text_export(session: Session, options: SessionExport, supporting_da
lines.append("-" * 20)
lines.append(next_steps.strip())
# Branding footer
lines.append("")
lines.append("---")
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
return "\n".join(lines)
@@ -524,6 +533,10 @@ def generate_html_export(session: Session, options: SessionExport, supporting_da
html_parts.append('<h2>Next Steps</h2>')
html_parts.append(f'<div style="white-space: pre-wrap; margin-bottom: 20px;">{html.escape(next_steps.strip())}</div>')
# Branding footer
html_parts.append('<hr style="margin-top: 32px; border: none; border-top: 1px solid #ddd;">')
html_parts.append('<p style="margin-top: 12px; font-size: 0.8em; color: #999; text-align: center;">Generated with <a href="https://resolutionflow.com" style="color: #06b6d4; text-decoration: none;">ResolutionFlow</a> — https://resolutionflow.com</p>')
html_parts.extend(['</body>', '</html>'])
return "\n".join(html_parts)
@@ -648,6 +661,11 @@ def generate_psa_export(session: Session, options: SessionExport, supporting_dat
scratchpad = getattr(session, 'scratchpad', '') or ''
lines.append(scratchpad.strip() if scratchpad.strip() else "None")
# Branding footer
lines.append("")
lines.append("---")
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
return "\n".join(lines)
@@ -737,6 +755,10 @@ def _generate_procedural_markdown(session: Session, options: SessionExport) -> s
lines.append(outcome_notes.strip())
lines.append("")
# Branding footer
lines.append("---")
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
return "\n".join(lines)
@@ -802,6 +824,11 @@ def _generate_procedural_text(session: Session, options: SessionExport) -> str:
lines.append("-" * 20)
lines.append(outcome_notes.strip())
# Branding footer
lines.append("")
lines.append("---")
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
return "\n".join(lines)
@@ -887,6 +914,10 @@ def _generate_procedural_html(session: Session, options: SessionExport) -> str:
html_parts.append('<h2>Notes</h2>')
html_parts.append(f'<div style="white-space: pre-wrap;">{html.escape(outcome_notes.strip())}</div>')
# Branding footer
html_parts.append('<hr style="margin-top: 32px; border: none; border-top: 1px solid #ddd;">')
html_parts.append('<p style="margin-top: 12px; font-size: 0.8em; color: #999; text-align: center;">Generated with <a href="https://resolutionflow.com" style="color: #06b6d4; text-decoration: none;">ResolutionFlow</a> — https://resolutionflow.com</p>')
html_parts.extend(['</body>', '</html>'])
return "\n".join(html_parts)
@@ -956,6 +987,11 @@ def _generate_procedural_psa(session: Session, options: SessionExport) -> str:
lines.append("--- TIME SPENT ---")
lines.append(f"Duration: {_format_duration(session.started_at, session.completed_at)}")
# Branding footer
lines.append("")
lines.append("---")
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
return "\n".join(lines)

View File

@@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8">
<style>
{% if has_custom_logo %}
@page {
size: A4;
margin: 2cm;
@@ -18,17 +17,6 @@
color: #999;
}
}
{% else %}
@page {
size: A4;
margin: 2cm;
@bottom-left {
content: "Generated {{ generated_at }}";
font-size: 8pt;
color: #999;
}
}
{% endif %}
* {
margin: 0;

View File

@@ -1,5 +1,5 @@
import { useState, useEffect } from 'react'
import { Copy, Download, Check, RotateCcw, FileDown } from 'lucide-react'
import { Copy, Download, Check, RotateCcw, FileDown, Loader2 } from 'lucide-react'
import { Modal } from '@/components/common/Modal'
import { cn } from '@/lib/utils'
import type { RedactionSummary } from '@/types'
@@ -149,7 +149,11 @@ export function ExportPreviewModal({
'disabled:opacity-60 disabled:cursor-not-allowed'
)}
>
<Download className="h-4 w-4" />
{pdfLoading ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<Download className="h-4 w-4" />
)}
{pdfLoading ? 'Generating PDF...' : 'Download PDF'}
</button>
</div>