import streamlit as st import streamlit.components.v1 as components import os, json, re from reportlab.lib.pagesizes import letter from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import inch from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, KeepTogether, PageBreak, ) from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT from reportlab.lib import colors from io import BytesIO from datetime import datetime from config import * # ── Shorthand color references NAVY = BRAND["colors"]["navy"] TEAL = BRAND["colors"]["teal"] SKY = BRAND["colors"]["sky"] ORANGE = BRAND["colors"]["orange"] AMBER = BRAND["colors"]["amber"] WHITE = BRAND["colors"]["white"] # ============================================================================= # RECOMMENDATION ENGINE # ============================================================================= def score_peptides(selected_goals): """Score every peptide against the patient's selected goals. Returns a list of (peptide_key, score, matched_categories) sorted by score descending, then by suggested-vial cost ascending (value-first tiebreaker). """ # Build category weights from selected goals cat_scores = {} for goal in selected_goals: for cat_name, weight in GOAL_MAPPINGS.get(goal, []): cat_scores[cat_name] = cat_scores.get(cat_name, 0) + weight if not cat_scores: return [] results = [] for pep_key, pep in PEPTIDES.items(): score = 0 matched = [] for cat in pep["categories"]: if cat in cat_scores: score += cat_scores[cat] matched.append(cat) if score > 0: results.append((pep_key, score, matched)) # Sort: highest score first, then cheapest suggested-vial price as tiebreaker results.sort( key=lambda x: ( -x[1], PEPTIDES[x[0]]["pricing"].get(PEPTIDES[x[0]]["suggested_vials"], 9999), ) ) return results def get_top_categories(selected_goals, limit=3): """Return the top N matched categories from selected goals.""" cat_scores = {} for goal in selected_goals: for cat_name, weight in GOAL_MAPPINGS.get(goal, []): cat_scores[cat_name] = cat_scores.get(cat_name, 0) + weight sorted_cats = sorted(cat_scores.items(), key=lambda x: -x[1]) return [c[0] for c in sorted_cats[:limit]] def group_by_tier(scored_peptides): """Group scored peptides into branded blends, other blends, and singles. Each tier is sorted high-to-low by score, then cheapest suggested price.""" branded = [] blends = [] singles = [] for pep_key, score, matched in scored_peptides: pep = PEPTIDES[pep_key] if pep.get("brand_name"): branded.append((pep_key, score, matched)) elif pep.get("is_blend"): blends.append((pep_key, score, matched)) else: singles.append((pep_key, score, matched)) # Ensure each tier is explicitly sorted: highest score first, most expensive suggested price first as tiebreaker _sort_key = lambda x: (-x[1], -PEPTIDES[x[0]]["pricing"].get(PEPTIDES[x[0]]["suggested_vials"], 0)) branded.sort(key=_sort_key) blends.sort(key=_sort_key) singles.sort(key=_sort_key) return branded, blends, singles # ============================================================================= # PDF GENERATOR # ============================================================================= def generate_pdf(patient_info, selected_goals, top_categories, recommendations): """Generate a branded PDF of the peptide recommendation.""" buffer = BytesIO() doc = SimpleDocTemplate( buffer, pagesize=letter, topMargin=0.55 * inch, bottomMargin=0.6 * inch, leftMargin=0.65 * inch, rightMargin=0.65 * inch, ) story = [] pw = letter[0] - 1.3 * inch def ps(name, **kwargs): return ParagraphStyle(name, **kwargs) C_NAVY = colors.HexColor(NAVY) C_TEAL = colors.HexColor(TEAL) C_ORANGE = colors.HexColor(ORANGE) C_AMBER = colors.HexColor(AMBER) C_SKY = colors.HexColor(SKY) C_LIGHT = colors.HexColor("#eef4f8") C_CARD = colors.HexColor("#f0f6fa") C_BORDER = colors.HexColor("#b8d0de") brand_s = ps("Br", fontName="Helvetica-Bold", fontSize=9, textColor=C_ORANGE, spaceAfter=0, alignment=TA_CENTER) title_s = ps("T", fontName="Helvetica-Bold", fontSize=20, leading=26, textColor=colors.white, spaceAfter=0, alignment=TA_CENTER) sub_s = ps("Su", fontName="Helvetica", fontSize=10, textColor=C_SKY, spaceAfter=0, alignment=TA_CENTER) meta_s = ps("Me", fontName="Helvetica", fontSize=9, leading=14, textColor=C_NAVY, spaceAfter=3) h2_s = ps("H2", fontName="Helvetica-Bold", fontSize=11, textColor=colors.white, spaceBefore=0, spaceAfter=0) h3_s = ps("H3", fontName="Helvetica-Bold", fontSize=10, textColor=C_NAVY, spaceBefore=4, spaceAfter=3) body_s = ps("B", fontName="Helvetica", fontSize=9.5, leading=15, textColor=C_NAVY, spaceAfter=5) bullet_s = ps("Bu", fontName="Helvetica", fontSize=9.5, leading=15, textColor=C_NAVY, leftIndent=14, spaceAfter=3) disc_s = ps("Di", fontName="Helvetica-Oblique", fontSize=8, leading=12, textColor=colors.HexColor("#4a6070"), spaceAfter=4) price_s = ps("Pr", fontName="Helvetica-Bold", fontSize=10, textColor=C_ORANGE, spaceAfter=2) pep_hdr_s = ps("Ph", fontName="Helvetica-Bold", fontSize=10, textColor=colors.white, spaceBefore=0, spaceAfter=0) ft_s = ps("Ft", fontName="Helvetica", fontSize=8, leading=12, textColor=C_NAVY, spaceAfter=0, alignment=TA_CENTER) def banner(para, bg, line_below=None, pad_v=7, pad_h=12): t = Table([[para]], colWidths=[pw]) cmds = [ ("BACKGROUND", (0, 0), (-1, -1), bg), ("LEFTPADDING", (0, 0), (-1, -1), pad_h), ("RIGHTPADDING", (0, 0), (-1, -1), pad_h), ("TOPPADDING", (0, 0), (-1, -1), pad_v), ("BOTTOMPADDING", (0, 0), (-1, -1), pad_v), ] if line_below: cmds.append(("LINEBELOW", (0, 0), (-1, -1), 3, line_below)) t.setStyle(TableStyle(cmds)) return t def section_hdr(text): return KeepTogether([ Spacer(1, 8), banner(Paragraph(text.upper(), h2_s), C_NAVY, line_below=C_ORANGE, pad_v=8), Spacer(1, 6), ]) # ── COVER ──────────────────────────────────────────────────────────────── hdr_tbl = Table([ [Paragraph("IGNITE PERFORMANCE & HEALTH", brand_s)], [Paragraph("Peptide Protocol Recommendation", title_s)], [Paragraph("Physician-Supervised Peptide Therapy", sub_s)], ], colWidths=[pw]) hdr_tbl.setStyle(TableStyle([ ("BACKGROUND", (0, 0), (-1, -1), C_NAVY), ("LEFTPADDING", (0, 0), (-1, -1), 20), ("RIGHTPADDING", (0, 0), (-1, -1), 20), ("TOPPADDING", (0, 0), (0, 0), 14), ("BOTTOMPADDING", (0, 0), (0, 0), 4), ("TOPPADDING", (0, 1), (0, 1), 4), ("BOTTOMPADDING", (0, 1), (0, 1), 4), ("TOPPADDING", (0, 2), (0, 2), 2), ("BOTTOMPADDING", (0, 2), (0, 2), 14), ("ALIGN", (0, 0), (-1, -1), "CENTER"), ])) story.append(hdr_tbl) story.append(HRFlowable(width="100%", thickness=5, color=C_ORANGE, spaceAfter=12)) # ── Patient info ── name = patient_info.get("name", "") date_str = datetime.now().strftime("%B %d, %Y") pi_tbl = Table([[ Paragraph(f"Prepared for: {name}", meta_s), Paragraph(f"Date: {date_str}", meta_s), ]], colWidths=[pw * 0.6, pw * 0.4]) pi_tbl.setStyle(TableStyle([ ("BACKGROUND", (0, 0), (-1, -1), C_LIGHT), ("BOX", (0, 0), (-1, -1), 0.75, C_BORDER), ("LINEBELOW", (0, 0), (-1, -1), 2, C_ORANGE), ("LEFTPADDING", (0, 0), (-1, -1), 10), ("RIGHTPADDING", (0, 0), (-1, -1), 10), ("TOPPADDING", (0, 0), (-1, -1), 9), ("BOTTOMPADDING", (0, 0), (-1, -1), 9), ("VALIGN", (0, 0), (-1, -1), "MIDDLE"), ])) story.append(pi_tbl) story.append(Spacer(1, 14)) # ── Goals & Categories ── story.append(section_hdr("Your Goals")) goals_text = " · ".join(selected_goals) story.append(Paragraph(f"Selected goals: {goals_text}", body_s)) cats_text = " · ".join(top_categories) story.append(Paragraph(f"Top therapeutic areas: {cats_text}", body_s)) story.append(Spacer(1, 8)) # ── Recommendations ── story.append(section_hdr("Recommended Peptides")) branded, blends, singles = group_by_tier(recommendations) def render_pep_block(pep_key, score, matched): pep = PEPTIDES[pep_key] display_name = pep.get("brand_name") or pep_key sv = pep["suggested_vials"] sv_price = pep["pricing"].get(sv, 0) per_week = sv_price / max((sv * 4), 1) # rough per-week estimate items = [ Spacer(1, 4), banner(Paragraph(f" {display_name}", pep_hdr_s), C_TEAL, line_below=C_NAVY, pad_v=5), ] if pep.get("brand_name") and pep_key != pep["brand_name"]: items.append(Paragraph(f"{pep_key}", disc_s)) items.append(Paragraph(pep["description"], body_s)) # ── Layered MOA ── moa_scott = pep.get("moa_scott", "") moa_clinical = pep.get("moa_clinical", "") if moa_scott: items.append(Paragraph(f'How it works: {moa_scott}', body_s)) if moa_clinical: items.append(Paragraph(f"{moa_clinical}", disc_s)) items.append(Paragraph( f"Dosage: {pep['dosage']} | Cycle: {pep['cycle']} | " f"Suggested vials: {sv}", bullet_s)) items.append(Paragraph( f"Suggested cycle cost: ${sv_price:,.2f} ({sv} vials) | " f"~${per_week:,.2f}/week", price_s)) items.append(Paragraph( f"Categories: {', '.join(matched)}", disc_s)) items.append(Spacer(1, 6)) return KeepTogether(items) if branded: story.append(Paragraph("Ignite Branded Blends — curated multi-peptide protocols", h3_s)) for pep_key, score, matched in branded[:6]: story.append(render_pep_block(pep_key, score, matched)) if blends: story.append(Paragraph("Combination Blends", h3_s)) for pep_key, score, matched in blends[:4]: story.append(render_pep_block(pep_key, score, matched)) if singles: story.append(Paragraph("Individual Peptides", h3_s)) for pep_key, score, matched in singles[:4]: story.append(render_pep_block(pep_key, score, matched)) # ── Disclaimer ── story.append(Spacer(1, 12)) story.append(HRFlowable(width="100%", thickness=1, color=C_BORDER, spaceAfter=8)) story.append(Paragraph(BRAND["disclaimer"], disc_s)) story.append(Spacer(1, 6)) # ── Footer ── story.append(HRFlowable(width="100%", thickness=3, color=C_ORANGE, spaceAfter=0)) ft_brand_s = ps("Fb", fontName="Helvetica-Bold", fontSize=10, textColor=C_ORANGE, spaceAfter=1, alignment=TA_CENTER) ft_info_s = ps("Fi", fontName="Helvetica", fontSize=8, leading=12, textColor=colors.white, spaceAfter=1, alignment=TA_CENTER) ft_web_s = ps("Fw", fontName="Helvetica-Bold", fontSize=8, textColor=C_SKY, spaceAfter=0, alignment=TA_CENTER) ft_tbl = Table([ [Paragraph("IGNITE PERFORMANCE & HEALTH", ft_brand_s)], [Paragraph("14830 Clayton Rd, Chesterfield, MO 63017 | (314) 887-0858 | info@ignitepah.com", ft_info_s)], [Paragraph("www.ignitepah.com", ft_web_s)], ], colWidths=[pw]) ft_tbl.setStyle(TableStyle([ ("BACKGROUND", (0, 0), (-1, -1), C_NAVY), ("TOPPADDING", (0, 0), (0, 0), 8), ("BOTTOMPADDING", (0, -1), (0, -1), 8), ("TOPPADDING", (0, 1), (-1, -1), 1), ("BOTTOMPADDING", (0, 1), (-1, -1), 1), ("ALIGN", (0, 0), (-1, -1), "CENTER"), ])) story.append(ft_tbl) doc.build(story) buffer.seek(0) return buffer # ============================================================================= # FOOTER RENDERER # ============================================================================= def render_footer(): st.markdown( '
', unsafe_allow_html=True, ) # ============================================================================= # PAGE CONFIG & CSS # ============================================================================= st.set_page_config( page_title="Ignite Performance & Health — Peptide Protocol Selector", layout="wide", initial_sidebar_state="collapsed", ) st.markdown( '' '' '', unsafe_allow_html=True, ) st.markdown(""" """, unsafe_allow_html=True) # ============================================================================= # SESSION STATE # ============================================================================= if "pep_results" not in st.session_state: st.session_state["pep_results"] = None st.session_state["pep_goals"] = [] st.session_state["pep_top_cats"] = [] st.session_state["pep_patient_name"] = "" st.session_state["pep_patient_email"] = "" st.session_state["pep_patient_phone"] = "" # ============================================================================= # RESULTS PAGE # ============================================================================= if st.session_state["pep_results"]: pname = st.session_state.get("pep_patient_name", "") pemail = st.session_state.get("pep_patient_email", "") pphone = st.session_state.get("pep_patient_phone", "") selected_goals = st.session_state.get("pep_goals", []) top_cats = st.session_state.get("pep_top_cats", []) results = st.session_state["pep_results"] # ── Hero ── st.markdown( '{goals_html}
', unsafe_allow_html=True) cats_html = " ".join(f'{c}' for c in top_cats) st.markdown(f'' 'Curated multi-peptide protocols from our proprietary blend line. These combine complementary peptides ' 'into a single vial for convenience and synergistic benefit.
', unsafe_allow_html=True, ) for pep_key, score, matched in branded[:6]: render_card(pep_key, score, matched, is_branded=True) if blends: st.markdown('' 'Single-peptide options for targeted protocols or for patients who prefer to build their stack one component at a time.
', unsafe_allow_html=True, ) for pep_key, score, matched in singles[:4]: render_card(pep_key, score, matched, is_branded=False) # ── CTA ── st.markdown( f'These recommendations are based on your stated goals. All peptide protocols require ' f'physician evaluation before we begin. Our team will walk through each option during your consultation, ' f'answer your questions, and build a protocol that fits your situation.
' f'What happens next: our team reaches out, we schedule your consultation, ' f'and we go from there.
' f'Contact: {pemail} | {pphone}
' f'Schedule Your Consultation' f'' f'{cat_name}
', unsafe_allow_html=True, ) for goal in cat["goals"]: goal_checks[goal] = st.checkbox(goal, key=f"g_{goal}") with c2: for cat_name in cat_keys[mid:]: cat = CATEGORIES[cat_name] st.markdown( f'' f'{cat_name}
', unsafe_allow_html=True, ) for goal in cat["goals"]: goal_checks[goal] = st.checkbox(goal, key=f"g_{goal}") st.markdown('' 'Important: This platform is ' 'not HIPAA-compliant. Do not share sensitive medical records, ' 'Social Security numbers, or information you would not disclose on a non-secure platform.
', unsafe_allow_html=True, ) consent = st.checkbox( "I understand this is an informational tool, not a prescription. " "All peptide protocols require physician evaluation and approval.", key="consent", ) submitted = st.form_submit_button("Find My Peptides", use_container_width=True) # ── Processing ── if submitted: selected_goals = [g for g, checked in goal_checks.items() if checked] errors = [] if not first_name: errors.append("First Name") if not last_name: errors.append("Last Name") if not email: errors.append("Email Address") if not phone: errors.append("Cell Phone") if not selected_goals: errors.append("At least one health goal") if not consent: errors.append("Consent acknowledgment") if errors: st.error(f"Please complete: **{', '.join(errors)}**") st.stop() results = score_peptides(selected_goals) top_cats = get_top_categories(selected_goals) if not results: st.warning("No peptides matched your selected goals. Please try different selections.") st.stop() st.session_state["pep_results"] = results st.session_state["pep_goals"] = selected_goals st.session_state["pep_top_cats"] = top_cats st.session_state["pep_patient_name"] = f"{first_name} {last_name}" st.session_state["pep_patient_email"] = email st.session_state["pep_patient_phone"] = phone st.rerun() render_footer()