historical-ocr / ui /layout.py
milwright's picture
Update Historical OCR with specified input files
59aaeae
raw
history blame
5.88 kB
import streamlit as st
from pathlib import Path
import os
# Load custom CSS
def load_css():
css_file = Path(__file__).parent / "custom.css"
if css_file.exists():
with open(css_file) as f:
st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
else:
st.warning("Custom CSS file not found. Some styles may be missing.")
# Header component
def header():
st.markdown("""
<div class="main-header">
<h1 class="title-text">Historical OCR Workshop</h1>
</div>
""", unsafe_allow_html=True)
# Create a page wrapper similar to the React component
def page_wrapper(content_function, current_module=1):
"""
Creates a consistent page layout with navigation
Args:
content_function: Function that renders the page content
current_module: Current module number (1-6)
"""
# Load custom CSS
load_css()
# Display header
header()
# Ensure session state for navigation
if 'current_module' not in st.session_state:
st.session_state.current_module = current_module
# Main content area with bottom padding for the nav
st.markdown('<div class="main-content">', unsafe_allow_html=True)
# Call the content function to render the module content
content_function()
# Add spacer for fixed nav
st.markdown('<div class="footer-spacer"></div>', unsafe_allow_html=True)
# Navigation
render_navigation(current_module)
st.markdown('</div>', unsafe_allow_html=True)
# Navigation component
def render_navigation(current_module):
# Define modules names like in React
modules = ['Introduction', 'Historical Context', 'Methodology', 'Case Studies', 'Interactive OCR', 'Conclusion']
# Navigation container
st.markdown(f"""
<div class="nav-container">
<div class="nav-buttons">
{prev_button_html(current_module, modules)}
{next_button_html(current_module, modules)}
</div>
<div class="nav-dots">
{nav_dots_html(current_module, modules)}
</div>
</div>
""", unsafe_allow_html=True)
# Previous button HTML
def prev_button_html(current_module, modules):
if current_module > 1:
prev_module = current_module - 1
return f"""
<button class="prev-button"
onclick="document.getElementById('nav_prev_{prev_module}').click()"
aria-label="Go to previous module: {modules[prev_module-1]}">
← Previous
</button>
"""
return ""
# Next button HTML
def next_button_html(current_module, modules):
if current_module < len(modules):
next_module = current_module + 1
return f"""
<button class="next-button"
onclick="document.getElementById('nav_next_{next_module}').click()"
aria-label="Go to next module: {modules[next_module-1]}">
Next β†’
</button>
"""
return ""
# Navigation dots HTML
def nav_dots_html(current_module, modules):
dots_html = ""
for i, name in enumerate(modules, 1):
active_class = "active" if i == current_module else ""
dots_html += f"""
<a class="nav-dot {active_class}"
onclick="document.getElementById('nav_dot_{i}').click()"
aria-current="{i == current_module}"
aria-label="Go to module {i}: {name}">
{i}
</a>
"""
return dots_html
# Helper functions for container styles
def gray_container(content, padding="1.5rem"):
"""Renders content in a gray container with consistent styling"""
st.markdown(f'<div class="content-container" style="padding:{padding};">{content}</div>', unsafe_allow_html=True)
def blue_container(content, padding="1.5rem"):
"""Renders content in a blue container with consistent styling"""
st.markdown(f'<div class="blue-container" style="padding:{padding};">{content}</div>', unsafe_allow_html=True)
def yellow_container(content, padding="1.5rem"):
"""Renders content in a yellow container with consistent styling"""
st.markdown(f'<div class="yellow-container" style="padding:{padding};">{content}</div>', unsafe_allow_html=True)
def card_grid(cards):
"""
Renders a responsive grid of cards
Args:
cards: List of HTML strings for each card
"""
grid_html = '<div class="card-grid">'
for card in cards:
grid_html += f'<div class="card">{card}</div>'
grid_html += '</div>'
st.markdown(grid_html, unsafe_allow_html=True)
def module_card(number, title, description):
"""Creates a styled module card"""
return f"""
<div class="module-card">
<div class="module-number">Module {number}</div>
<div class="module-title">{title}</div>
<p>{description}</p>
</div>
"""
def key_concept(content):
"""Renders a key concept box"""
st.markdown(f'<div class="key-concept">{content}</div>', unsafe_allow_html=True)
def research_question(content):
"""Renders a research question box"""
st.markdown(f'<div class="research-question">{content}</div>', unsafe_allow_html=True)
def quote(content, author=""):
"""Renders a quote with optional author"""
quote_html = f'<div class="quote-container">{content}'
if author:
quote_html += f'<br/><br/><span style="font-size:0.9rem; text-align:right; display:block;">β€” {author}</span>'
quote_html += '</div>'
st.markdown(quote_html, unsafe_allow_html=True)
def tool_container(content):
"""Renders content in a tool container"""
st.markdown(f'<div class="tool-container">{content}</div>', unsafe_allow_html=True)
def upload_container(content):
"""Renders content in an upload container"""
st.markdown(f'<div class="upload-container">{content}</div>', unsafe_allow_html=True)