| |
|
| |
|
| | import os
|
| | from pathlib import Path
|
| | import streamlit as st
|
| |
|
| |
|
| | try:
|
| | from Config.settings import PAGE_SIZE_DEFAULT
|
| | except Exception:
|
| | try:
|
| | from config.settings import PAGE_SIZE_DEFAULT
|
| | except Exception:
|
| | PAGE_SIZE_DEFAULT = 12
|
| |
|
| |
|
| | try:
|
| | from core.gallery_storage import (
|
| | save_report_image,
|
| | gallery_list_images_sorted,
|
| | delete_report_image,
|
| | )
|
| | except Exception:
|
| | from gallery_storage import (
|
| | save_report_image,
|
| | gallery_list_images_sorted,
|
| | delete_report_image,
|
| | )
|
| |
|
| |
|
| | def render_reports_gallery_uploader(key_prefix: str) -> None:
|
| | """Uploader de imagens para a galeria (qualquer usuário)."""
|
| | st.subheader("📤 Publicar foto do relatório")
|
| | st.caption("Envie uma imagem (JPG/PNG/WEBP). Todos os usuários poderão visualizar na galeria.")
|
| |
|
| | uploader_name = ""
|
| | uploader_email = ""
|
| | if st.session_state.get("aluno_logged_in"):
|
| | uploader_name = st.session_state.get("aluno_nome") or ""
|
| | uploader_email = st.session_state.get("aluno_email") or ""
|
| | elif st.session_state.get("is_admin"):
|
| | uploader_name = st.session_state.get("admin_user") or ""
|
| |
|
| | col_name, _ = st.columns([2, 3])
|
| | name_input = col_name.text_input(
|
| | "Seu nome (opcional)",
|
| | value=uploader_name,
|
| | max_chars=40,
|
| | placeholder="Ex.: Rodrigo",
|
| | key=f"{key_prefix}gallery_name_input",
|
| | )
|
| |
|
| | up = st.file_uploader(
|
| | "Selecione a imagem do relatório",
|
| | type=["png", "jpg", "jpeg", "webp"],
|
| | accept_multiple_files=False,
|
| | help="Dica: até ~5MB carrega mais rápido",
|
| | key=f"{key_prefix}gallery_file_uploader",
|
| | )
|
| |
|
| | if up:
|
| | try:
|
| | st.image(up, caption="Pré-visualização", use_container_width=True)
|
| | except Exception:
|
| | st.info("Pré-visualização indisponível para este arquivo.")
|
| |
|
| | publish_col, _ = st.columns([1, 3])
|
| | if publish_col.button(
|
| | "📌 Publicar",
|
| | type="primary",
|
| | use_container_width=True,
|
| | disabled=(up is None),
|
| | key=f"{key_prefix}gallery_publish_btn",
|
| | ):
|
| | if up is None:
|
| | st.warning("Selecione uma imagem antes de publicar.")
|
| | return
|
| | try:
|
| | saved = save_report_image(
|
| | uploaded_file=up,
|
| | uploader_name=(name_input or None),
|
| | uploader_email=(uploader_email or None),
|
| | )
|
| | if saved:
|
| | st.success("Imagem publicada com sucesso!")
|
| | st.rerun()
|
| | except Exception as e:
|
| | st.error(f"Falha ao salvar imagem: {e}")
|
| |
|
| |
|
| | def render_reports_gallery_grid(page_size: int = PAGE_SIZE_DEFAULT, key_prefix: str = "") -> None:
|
| | """Grade com miniaturas + download; exclusão apenas para Admin (server-side check)."""
|
| | st.subheader("🖼️ Galeria de Relatórios")
|
| | imgs = gallery_list_images_sorted()
|
| | if not imgs:
|
| | st.info("Ainda não há imagens publicadas.")
|
| | return
|
| |
|
| | import math
|
| |
|
| | total = len(imgs)
|
| | pages = max(1, math.ceil(total / page_size))
|
| |
|
| | key_page = f"{key_prefix}gallery_page"
|
| | st.session_state.setdefault(key_page, 1)
|
| |
|
| | cur_page = st.session_state[key_page]
|
| | if cur_page > pages:
|
| | cur_page = pages
|
| | st.session_state[key_page] = cur_page
|
| | if cur_page < 1:
|
| | cur_page = 1
|
| | st.session_state[key_page] = cur_page
|
| |
|
| | col_left, col_center, col_right = st.columns([1, 3, 1])
|
| | with col_left:
|
| | if st.button("⬅️", disabled=(cur_page <= 1), key=f"{key_prefix}gallery_nav_prev"):
|
| | st.session_state[key_page] = max(1, cur_page - 1)
|
| | st.rerun()
|
| | with col_center:
|
| | sel = st.selectbox(
|
| | "Página",
|
| | options=list(range(1, pages + 1)),
|
| | index=cur_page - 1,
|
| | key=f"{key_prefix}gallery_page_select",
|
| | label_visibility="collapsed",
|
| | )
|
| | if sel != cur_page:
|
| | st.session_state[key_page] = sel
|
| | st.rerun()
|
| | with col_right:
|
| | if st.button("➡️", disabled=(cur_page >= pages), key=f"{key_prefix}gallery_nav_next"):
|
| | st.session_state[key_page] = min(pages, cur_page + 1)
|
| | st.rerun()
|
| |
|
| | st.caption(
|
| | f"Mostrando {page_size} por página — {total} imagens no total · "
|
| | f"Página {st.session_state.get(key_page, 1)} de {pages}"
|
| | )
|
| |
|
| | start = (st.session_state[key_page] - 1) * page_size
|
| | end = min(start + page_size, total)
|
| | page_items = imgs[start:end]
|
| |
|
| | cols = st.columns(3)
|
| | is_admin = bool(st.session_state.get("is_admin"))
|
| |
|
| | for i, (name, mtime, orig_path, thumb_path) in enumerate(page_items):
|
| | col = cols[i % 3]
|
| | with col:
|
| | try:
|
| | if Path(thumb_path).exists():
|
| | col.image(str(thumb_path), use_container_width=True, caption=name)
|
| | else:
|
| | col.image(str(orig_path), use_container_width=True, caption=name)
|
| | except Exception:
|
| | col.warning(f"Não foi possível carregar {name}.")
|
| | continue
|
| |
|
| |
|
| | try:
|
| | with open(orig_path, "rb") as f:
|
| | mime = "image/jpeg" if name.lower().endswith((".jpg", ".jpeg")) else "image/png"
|
| | st.download_button(
|
| | label="⬇️ Baixar original",
|
| | data=f,
|
| | file_name=name,
|
| | mime=mime,
|
| | use_container_width=True,
|
| | key=f"{key_prefix}dl_{name}",
|
| | )
|
| | except Exception as e:
|
| | col.warning(f"Download indisponível: {e}")
|
| |
|
| |
|
| | if is_admin:
|
| | if st.button("🗑️ Remover", key=f"{key_prefix}rm_{name}", type="secondary", use_container_width=True):
|
| | try:
|
| | delete_report_image(filename=name, is_admin=True)
|
| | st.success("Imagem removida.")
|
| | st.rerun()
|
| | except PermissionError as e:
|
| | st.error(str(e))
|
| | except Exception as e:
|
| | st.error(f"Erro ao remover: {e}")
|
| | else:
|
| | st.caption("Somente Admin pode excluir.")
|
| |
|
| |
|
| | def aba_galeria_relatorios(context_key: str) -> None:
|
| | """Aba completa: upload + grid (keys isoladas por contexto)."""
|
| | with st.container(border=True):
|
| | render_reports_gallery_uploader(key_prefix=context_key)
|
| | st.divider()
|
| | render_reports_gallery_grid(page_size=PAGE_SIZE_DEFAULT, key_prefix=context_key) |