Spaces:
Sleeping
Sleeping
| """ | |
| Export supervision notes and CPD logs to .docx format. | |
| """ | |
| from datetime import date | |
| from io import BytesIO | |
| HAS_DOCX = False | |
| try: | |
| from docx import Document | |
| from docx.shared import Pt, RGBColor, Inches | |
| from docx.enum.text import WD_ALIGN_PARAGRAPH | |
| HAS_DOCX = True | |
| except ImportError: | |
| pass | |
| def build_supervision_docx(note_text: str, nurse_name: str = "") -> bytes | None: | |
| """Build a formatted .docx supervision note.""" | |
| if not HAS_DOCX: | |
| return None | |
| doc = Document() | |
| # Header | |
| header_para = doc.add_paragraph() | |
| header_para.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| run = header_para.add_run("Professional Nurse Advocate Assistant") | |
| run.bold = True | |
| run.font.size = Pt(16) | |
| run.font.color.rgb = RGBColor(0x1a, 0x24, 0x60) # brand navy | |
| sub = doc.add_paragraph() | |
| sub.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| sub.add_run("A-EQUIP Model Supervision Note").italic = True | |
| doc.add_paragraph() | |
| # Metadata | |
| meta = doc.add_paragraph() | |
| meta.add_run(f"Date: ").bold = True | |
| meta.add_run(date.today().strftime("%d %B %Y")) | |
| if nurse_name: | |
| nurse_p = doc.add_paragraph() | |
| nurse_p.add_run("Name: ").bold = True | |
| nurse_p.add_run(nurse_name) | |
| doc.add_paragraph() | |
| # Note content — parse markdown-ish headings | |
| for line in note_text.split("\n"): | |
| line = line.strip() | |
| if not line: | |
| doc.add_paragraph() | |
| continue | |
| if line.startswith("## "): | |
| h = doc.add_heading(line[3:], level=2) | |
| for run in h.runs: | |
| run.font.color.rgb = RGBColor(0x1a, 0x24, 0x60) | |
| elif line.startswith("### "): | |
| h = doc.add_heading(line[4:], level=3) | |
| for run in h.runs: | |
| run.font.color.rgb = RGBColor(0x0d, 0x94, 0x88) # teal | |
| elif line.startswith("**") and line.endswith("**"): | |
| p = doc.add_paragraph() | |
| p.add_run(line.strip("**")).bold = True | |
| elif line.startswith("- "): | |
| doc.add_paragraph(line[2:], style="List Bullet") | |
| else: | |
| doc.add_paragraph(line) | |
| # Footer | |
| doc.add_paragraph() | |
| footer = doc.add_paragraph() | |
| footer.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| footer_run = footer.add_run( | |
| "Contains public sector information licensed under the Open Government Licence v3.0 — NHS England.\n" | |
| "This tool supports but does not replace clinical judgment or formal supervision documentation." | |
| ) | |
| footer_run.font.size = Pt(8) | |
| footer_run.font.color.rgb = RGBColor(0x6b, 0x72, 0x80) | |
| footer_run.italic = True | |
| buf = BytesIO() | |
| doc.save(buf) | |
| return buf.getvalue() | |
| def build_cpd_docx(note_text: str, nurse_name: str = "", hours: float = 1.0) -> bytes | None: | |
| """Build NMC revalidation CPD record.""" | |
| if not HAS_DOCX: | |
| return None | |
| doc = Document() | |
| header_para = doc.add_paragraph() | |
| header_para.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| run = header_para.add_run("NMC Revalidation — CPD Record") | |
| run.bold = True | |
| run.font.size = Pt(16) | |
| run.font.color.rgb = RGBColor(0x1a, 0x24, 0x60) | |
| doc.add_paragraph() | |
| fields = [ | |
| ("Date", date.today().strftime("%d %B %Y")), | |
| ("Name", nurse_name or "___________________"), | |
| ("NMC PIN", "___________________"), | |
| ("Activity Type", "Restorative Clinical Supervision (A-EQUIP Model)"), | |
| ("Hours", f"{hours:.1f}"), | |
| ("Method", "1:1 Supervision with AI-assisted preparation/reflection"), | |
| ("NMC Standards", | |
| "Platform 1 (Accountable professional), Platform 6 (Safety & quality)"), | |
| ] | |
| for label, value in fields: | |
| p = doc.add_paragraph() | |
| p.add_run(f"{label}: ").bold = True | |
| p.add_run(value) | |
| doc.add_paragraph() | |
| doc.add_heading("Supervision Summary", level=2) | |
| for line in note_text.split("\n"): | |
| line = line.strip() | |
| if not line: | |
| continue | |
| if line.startswith("### "): | |
| doc.add_heading(line[4:], level=3) | |
| elif line.startswith("- "): | |
| doc.add_paragraph(line[2:], style="List Bullet") | |
| elif not line.startswith("## ") and not line.startswith("**Date"): | |
| doc.add_paragraph(line) | |
| doc.add_paragraph() | |
| sig_p = doc.add_paragraph() | |
| sig_p.add_run("Nurse signature: ").bold = True | |
| sig_p.add_run("_________________________") | |
| conf_p = doc.add_paragraph() | |
| conf_p.add_run("Confirming PNA/Supervisor: ").bold = True | |
| conf_p.add_run("_________________________") | |
| doc.add_paragraph() | |
| footer = doc.add_paragraph() | |
| footer.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| fr = footer.add_run( | |
| "Contains public sector information licensed under the Open Government Licence v3.0 — NHS England." | |
| ) | |
| fr.font.size = Pt(8) | |
| fr.italic = True | |
| buf = BytesIO() | |
| doc.save(buf) | |
| return buf.getvalue() | |