Krika commited on
Commit
edaee4b
Β·
2 Parent(s): fe444401f8721e

Merge branch 'main' of https://github.com/Alalalallalalalalalalalal/Frontend

Browse files
Files changed (1) hide show
  1. phase/Student_view/lesson.py +74 -138
phase/Student_view/lesson.py CHANGED
@@ -18,72 +18,6 @@ USE_LOCAL_DB = os.getenv("DISABLE_DB", "1") != "1"
18
 
19
  FALLBACK_TAG = "<!--fallback-->"
20
 
21
-
22
- # ---- NEW: minimal Markdown -> HTML helper (keeps cards as single HTML blocks)
23
- def _md_to_html(text: str) -> str:
24
- """
25
- Best-effort conversion so markdown-like lesson text can live *inside* a single HTML block.
26
- Uses python-markdown if available; otherwise a tiny fallback that handles paragraphs + bullets.
27
- """
28
- if not text:
29
- return ""
30
- try:
31
- # If python-markdown is available, use it for better fidelity.
32
- from markdown import markdown as _mk
33
- return _mk(text, extensions=["extra", "sane_lists"])
34
- except Exception:
35
- # Fallback: paragraphs + simple lists
36
- lines = text.strip().splitlines()
37
- html_parts = []
38
- in_ul = False
39
-
40
- def close_ul():
41
- nonlocal in_ul
42
- if in_ul:
43
- html_parts.append("</ul>")
44
- in_ul = False
45
-
46
- for ln in lines:
47
- s = ln.rstrip()
48
- if not s:
49
- close_ul()
50
- html_parts.append("<p></p>")
51
- continue
52
-
53
- # Headings (#, ##, ###) basic support
54
- if s.startswith("### "):
55
- close_ul()
56
- html_parts.append(f"<h3>{s[4:].strip()}</h3>")
57
- continue
58
- if s.startswith("## "):
59
- close_ul()
60
- html_parts.append(f"<h2>{s[3:].strip()}</h2>")
61
- continue
62
- if s.startswith("# "):
63
- close_ul()
64
- html_parts.append(f"<h1>{s[2:].strip()}</h1>")
65
- continue
66
-
67
- # Bullet lines
68
- bullet_prefixes = ("- ", "* ", "β€’ ", "– ")
69
- if s.startswith(bullet_prefixes):
70
- if not in_ul:
71
- html_parts.append("<ul>")
72
- in_ul = True
73
- html_parts.append(f"<li>{s[2:].strip()}</li>")
74
- continue
75
-
76
- # Regular paragraph
77
- close_ul()
78
- # light bold/italic
79
- p = re.sub(r"\*\*(.+?)\*\*", r"<strong>\1</strong>", s)
80
- p = re.sub(r"\*(.+?)\*", r"<em>\1</em>", p)
81
- html_parts.append(f"<p>{p}</p>")
82
-
83
- close_ul()
84
- return "\n".join(html_parts)
85
-
86
-
87
  # --- Load external CSS (optional) ---
88
  def load_css(file_name: str):
89
  try:
@@ -483,9 +417,6 @@ def _get_topics(level: str, module_id: int) -> List[Tuple[str, str]]:
483
 
484
 
485
  def _render_lesson():
486
- ensure_quiz_state()
487
- # make sure quiz keys exist
488
-
489
  """Render the lesson interface"""
490
  level = st.session_state.get("level", "beginner")
491
  module_id = st.session_state.get("module_id")
@@ -638,50 +569,51 @@ def _render_lesson():
638
  with col_main:
639
  t_title, t_text = topics[topic_idx]
640
 
641
- # ---- CHANGED: Build the entire lesson card in ONE HTML render
642
- lesson_html_text = _md_to_html((t_text or "").strip())
643
-
644
- takeaways_html = ""
645
- if t_text:
646
- takeaways = _extract_takeaways(t_text)
647
- if takeaways:
648
- takeaways_html = (
649
- '<div class="takeaways-section" style="min-height: 150px;">'
650
- ' <div class="takeaways-header">'
651
- ' <span style="color: #10b981;">●</span>'
652
- ' <span>Key Takeaways</span>'
653
- ' </div>'
654
- + "".join(
655
- f'<div class="takeaway-item"><span class="takeaway-check">βœ“</span><span>{st.escape_markdown(x)}</span></div>'
656
- for x in takeaways
657
- )
658
- + "</div>"
659
- )
660
-
661
- card_html = f"""
662
- <div class="lesson-card">
663
- <div class="unit-header">
664
- <span class="unit-info">Unit {topic_idx + 1} of {len(topics)}</span>
665
- <div class="read-time">
666
- <span>πŸ•</span>
667
- <span>5-8 min read</span>
668
- </div>
669
- </div>
670
- <div class="lesson-content">
671
- {lesson_html_text}
672
  </div>
673
- {takeaways_html}
674
  </div>
675
- """
676
- st.markdown(card_html, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
677
 
678
- # Navigation buttons (stay as Streamlit widgets)
679
  st.markdown('<div class="nav-buttons">', unsafe_allow_html=True)
 
680
  col1, col2, col3 = st.columns([1, 1, 1])
681
  with col1:
682
  if st.button("← Previous", disabled=topic_idx == 0, key="prev_btn"):
683
  st.session_state.topic_idx -= 1
684
  st.rerun()
 
685
  with col3:
686
  is_last = topic_idx >= len(topics) - 1
687
  if is_last:
@@ -695,53 +627,57 @@ def _render_lesson():
695
  if st.button("Next Unit β†’", key="next_btn"):
696
  st.session_state.topic_idx += 1
697
  st.rerun()
 
698
  st.markdown('</div>', unsafe_allow_html=True)
699
 
700
  with col_sidebar:
701
- # ---- CHANGED: Render sidebar progress as a single HTML block (so it's inside the card)
702
- progress = (topic_idx + 1) / max(1, len(topics))
703
- progress_pct = int(progress * 100)
704
-
705
- progress_html = f"""
706
  <div class="sidebar-card" style="min-height: 120px;">
707
  <h4>Module Progress</h4>
708
- <div style="width:100%;height:10px;background:#e5e7eb;border-radius:8px;overflow:hidden;">
709
- <div style="height:10px;width:{progress_pct}%;background:#10b981;"></div>
710
- </div>
711
- <p style="color:#6b7280;font-size:0.875rem;margin-top:0.5rem;">
712
- Unit {topic_idx + 1} of {len(topics)}
713
- </p>
714
- </div>
715
- """
716
- st.markdown(progress_html, unsafe_allow_html=True)
717
-
718
- # ---- CHANGED: Render the "Module Units" list as one HTML block too
719
- units_html = '<div class="sidebar-card" style="min-height: 300px;"><h4>Module Units</h4>'
 
 
720
  for i, (tt, _) in enumerate(topics):
721
- if i == topic_idx:
722
- units_html += f"""
 
 
 
723
  <div class="unit-item">
724
- <span style="background:#10b981;color:white;width:20px;height:20px;border-radius:50%;
725
- display:flex;align-items:center;justify-content:center;font-size:0.75rem;">●</span>
726
  <span class="unit-active">{tt}</span>
727
- </div>"""
728
- elif i < topic_idx:
729
- units_html += f"""
 
730
  <div class="unit-item">
731
- <span style="color:#10b981;font-size:1.1rem;">βœ“</span>
732
- <span style="color:#374151;">{tt}</span>
733
- </div>"""
 
734
  else:
735
- units_html += f"""
736
  <div class="unit-item">
737
- <span style="background:#e5e7eb;color:#9ca3af;width:20px;height:20px;border-radius:50%;
738
- display:flex;align-items:center;justify-content:center;font-size:0.75rem;">β—‹</span>
739
  <span class="unit-inactive">{tt}</span>
740
- </div>"""
741
- units_html += "</div>"
742
- st.markdown(units_html, unsafe_allow_html=True)
 
743
 
744
- # Back to modules button (Streamlit widget outside HTML block)
745
  if st.button("← Back to Modules", key="back_modules"):
746
  st.session_state.mode = "catalog"
747
  st.session_state.module_id = None
 
18
 
19
  FALLBACK_TAG = "<!--fallback-->"
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  # --- Load external CSS (optional) ---
22
  def load_css(file_name: str):
23
  try:
 
417
 
418
 
419
  def _render_lesson():
 
 
 
420
  """Render the lesson interface"""
421
  level = st.session_state.get("level", "beginner")
422
  module_id = st.session_state.get("module_id")
 
569
  with col_main:
570
  t_title, t_text = topics[topic_idx]
571
 
572
+ st.markdown(f"""
573
+ <div class="lesson-card">
574
+ <div class="unit-header">
575
+ <span class="unit-info">Unit {topic_idx + 1} of {len(topics)}</span>
576
+ <div class="read-time">
577
+ <span>πŸ•</span>
578
+ <span>5-8 min read</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  </div>
 
580
  </div>
581
+ <div class="lesson-content">
582
+ {t_text.strip() if t_text else "<p>Content coming soon.</p>"}
583
+ </div>
584
+ """, unsafe_allow_html=True)
585
+
586
+ # Conditionally render takeaways inside the card
587
+ if t_text:
588
+ takeaways = _extract_takeaways(t_text)
589
+ if takeaways:
590
+ st.markdown(f"""
591
+ <div class="takeaways-section">
592
+ <div class="takeaways-header">
593
+ <span style="color: #10b981;">●</span>
594
+ <span>Key Takeaways</span>
595
+ </div>
596
+ {''.join([
597
+ f'<div class="takeaway-item"><span class="takeaway-check">βœ“</span><span>{tk}</span></div>'
598
+ for tk in takeaways
599
+ ])}
600
+ </div>
601
+ </div> <!-- Closing lesson-card -->
602
+ """, unsafe_allow_html=True)
603
+ else:
604
+ st.markdown("</div>", unsafe_allow_html=True) # Close .lesson-card
605
+ else:
606
+ st.markdown("</div>", unsafe_allow_html=True) # Close .lesson-card if no takeaways
607
+
608
 
 
609
  st.markdown('<div class="nav-buttons">', unsafe_allow_html=True)
610
+
611
  col1, col2, col3 = st.columns([1, 1, 1])
612
  with col1:
613
  if st.button("← Previous", disabled=topic_idx == 0, key="prev_btn"):
614
  st.session_state.topic_idx -= 1
615
  st.rerun()
616
+
617
  with col3:
618
  is_last = topic_idx >= len(topics) - 1
619
  if is_last:
 
627
  if st.button("Next Unit β†’", key="next_btn"):
628
  st.session_state.topic_idx += 1
629
  st.rerun()
630
+
631
  st.markdown('</div>', unsafe_allow_html=True)
632
 
633
  with col_sidebar:
634
+ # Module Progress Card
635
+ st.markdown("""
 
 
 
636
  <div class="sidebar-card" style="min-height: 120px;">
637
  <h4>Module Progress</h4>
638
+ """, unsafe_allow_html=True)
639
+
640
+ progress = (topic_idx + 1) / max(1, len(topics))
641
+ st.progress(progress)
642
+ st.markdown(f"<p style='color: #6b7280; font-size: 0.875rem; margin-top: 0.5rem;'>Unit {topic_idx + 1} of {len(topics)}</p>", unsafe_allow_html=True)
643
+
644
+ st.markdown("</div>", unsafe_allow_html=True)
645
+
646
+ # Module Units Card
647
+ st.markdown("""
648
+ <div class="sidebar-card" style="min-height: 300px;">
649
+ <h4>Module Units</h4>
650
+ """, unsafe_allow_html=True)
651
+
652
  for i, (tt, _) in enumerate(topics):
653
+ is_current = i == topic_idx
654
+ is_completed = i < topic_idx
655
+
656
+ if is_current:
657
+ st.markdown(f"""
658
  <div class="unit-item">
659
+ <span style="background: #10b981; color: white; width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.75rem;">●</span>
 
660
  <span class="unit-active">{tt}</span>
661
+ </div>
662
+ """, unsafe_allow_html=True)
663
+ elif is_completed:
664
+ st.markdown(f"""
665
  <div class="unit-item">
666
+ <span style="color: #10b981; font-size: 1.1rem;">βœ“</span>
667
+ <span style="color: #374151;">{tt}</span>
668
+ </div>
669
+ """, unsafe_allow_html=True)
670
  else:
671
+ st.markdown(f"""
672
  <div class="unit-item">
673
+ <span style="background: #e5e7eb; color: #9ca3af; width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.75rem;">β—‹</span>
 
674
  <span class="unit-inactive">{tt}</span>
675
+ </div>
676
+ """, unsafe_allow_html=True)
677
+
678
+ st.markdown("</div>", unsafe_allow_html=True)
679
 
680
+ # Back to modules button
681
  if st.button("← Back to Modules", key="back_modules"):
682
  st.session_state.mode = "catalog"
683
  st.session_state.module_id = None