Spaces:
Runtime error
Runtime error
File size: 7,013 Bytes
3bb2388 8673167 3bb2388 8673167 3bb2388 8673167 3bb2388 8673167 3bb2388 2eb4389 3bb2388 8673167 3bb2388 8673167 3bb2388 9dcf3c3 3bb2388 9dcf3c3 3bb2388 9dcf3c3 3bb2388 9dcf3c3 3bb2388 9dcf3c3 3bb2388 9dcf3c3 3bb2388 8673167 8848482 3bb2388 2eb4389 3bb2388 2eb4389 3bb2388 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | import streamlit as st
from db import (
fetch_room_names,
fetch_room_names_by_owner,
topic_owner_column_available,
topic_entry_code_column_available,
upsert_topic_room,
)
from validators import (
normalize_user_text,
validate_entry_code,
validate_opinion_content,
validate_room_name,
)
from utils import log_audit
from config import MAX_ROOM_NAME_LEN, MAX_TOPIC_LEN, MAX_ENTRY_CODE_LEN
from components.teacher_auth import render_teacher_auth
def _reset_joined_state():
st.session_state['joined'] = False
st.session_state['teacher_auth'] = False
st.session_state['admin_auth'] = False
st.session_state['teacher_id'] = ""
st.session_state.pop('_admin_redirected', None)
def render_sidebar(supabase) -> dict:
with st.sidebar:
st.header("👤 접속 권한")
user_role = st.radio("모드 선택", ["학생", "교사"], on_change=_reset_joined_state)
st.divider()
try:
all_rooms = fetch_room_names(supabase)
except Exception:
all_rooms = []
room_name = ""
teacher_auth = False
admin_auth = False
student_number = ""
if user_role == "교사":
render_teacher_auth(supabase)
teacher_auth = st.session_state['teacher_auth']
admin_auth = st.session_state['admin_auth']
teacher_id_for_scope = st.session_state.get("teacher_id", "")
if teacher_auth:
existing_rooms = all_rooms if admin_auth else (
fetch_room_names_by_owner(supabase, teacher_id_for_scope)
if topic_owner_column_available()
else []
)
if not admin_auth and not topic_owner_column_available():
st.warning("교사별 방 조회를 위해 topic.created_by_teacher_id(권장) 또는 topic.created_by 컬럼이 필요합니다.")
room_opt = st.radio("방 관리", ["기존 방 선택", "새 방 만들기"])
if room_opt == "기존 방 선택":
if existing_rooms:
current = st.session_state.get('current_room', '')
default_idx = existing_rooms.index(current) if current in existing_rooms else 0
room_name = st.selectbox("토론/토의방 목록", existing_rooms, index=default_idx)
else:
st.info("아직 개설된 방이 없습니다. '새 방 만들기'를 선택해 첫 번째 방을 만들어보세요.")
room_name = ""
else:
new_room = st.text_input("새로 만들 방 이름 (예: 1학년 3반)")
new_title = st.text_input("주제 직접 입력 (예: 인공지능 윤리)")
new_mode = st.radio("진행 방식", ["⚔️ 찬반 토론", "💡 자유 토의"], horizontal=True)
new_pw = st.text_input("🔒 학생 입장용 암호 (비워두면 공개방)")
if st.button("새 방 개설하기", type="primary"):
room_ok, safe_new_room, _, room_error_message = validate_room_name(new_room, max_len=MAX_ROOM_NAME_LEN)
title_ok, safe_new_title, _, title_error_message = validate_opinion_content(new_title, max_len=MAX_TOPIC_LEN)
entry_ok, safe_new_pw, _, entry_error_message = validate_entry_code(new_pw, max_len=MAX_ENTRY_CODE_LEN)
can_store_room_pw = topic_entry_code_column_available()
if not room_ok:
st.error(f"❌ {room_error_message}")
elif not title_ok:
st.error(f"❌ {title_error_message}")
elif not entry_ok:
st.error(f"❌ {entry_error_message}")
elif safe_new_pw and not can_store_room_pw:
st.error("현재 DB 구조에서는 방 비밀번호 저장을 지원하지 않습니다.")
elif safe_new_room and safe_new_title:
res = upsert_topic_room(
supabase=supabase, room_name=safe_new_room, title=safe_new_title,
mode=new_mode, entry_code=safe_new_pw, created_by=teacher_id_for_scope,
)
if res is not None:
fetch_room_names.clear()
fetch_room_names_by_owner.clear()
st.session_state['current_room'] = safe_new_room
st.toast(f"'{safe_new_room}' 방이 개설되었습니다!", icon="🎉")
st.rerun()
room_name = ""
else:
st.session_state['teacher_auth'] = False
st.session_state['admin_auth'] = False
st.session_state['teacher_id'] = ""
if st.session_state.get('page') == "admin_approval":
st.session_state['page'] = "lobby"
_joined = st.session_state.get('joined', False)
student_number = st.text_input(
"학번",
key="student_number_input",
placeholder="예: 1101",
disabled=_joined,
help="방 입장 후에는 학번을 변경할 수 없습니다." if _joined else None,
)
if all_rooms:
room_name = st.selectbox("🏠 접속할 방 선택", all_rooms)
else:
st.warning("선생님이 아직 열어둔 방이 없습니다.")
room_name = ""
student_name = normalize_user_text(student_number, max_len=20) if user_role == "학생" else "교사"
if room_name and room_name != st.session_state['current_room']:
prev_room = st.session_state['current_room']
st.session_state['current_room'] = room_name
st.session_state['ai_hint_text'] = ""
st.session_state['ai_report_text'] = ""
st.session_state.pop('_admin_redirected', None)
if st.session_state['joined']:
st.session_state['joined'] = False
log_audit("room_switched_to_lobby", room_name=room_name, actor_name=student_name, role=user_role, previous_room=prev_room)
st.rerun()
if st.session_state['joined']:
st.divider()
if st.button("🚪 방 나가기 (대기실로)"):
st.session_state['joined'] = False
st.session_state.pop('_admin_redirected', None)
st.rerun()
return {
'user_role': user_role,
'room_name': room_name,
'teacher_auth': teacher_auth,
'admin_auth': admin_auth,
'student_name': student_name,
'student_number': student_number,
}
|