SarahXia0405 commited on
Commit
b0b8b96
·
verified ·
1 Parent(s): 003b570

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -52
app.py CHANGED
@@ -31,6 +31,7 @@ from syllabus_utils import extract_course_topics_from_file
31
  HANBRIDGE_LOGO_PATH = "hanbridge_logo.png"
32
  CLARE_LOGO_PATH = "clare_mascot.png"
33
  CLARE_RUN_PATH = "Clare_Run.png"
 
34
 
35
  # ================== Base64 Helper ==================
36
  def image_to_base64(image_path):
@@ -187,13 +188,32 @@ CUSTOM_CSS = """
187
  /* --- Main Header --- */
188
  .header-container { padding: 10px 20px; background-color: #ffffff; border-bottom: 2px solid #f3f4f6; margin-bottom: 15px; display: flex; align-items: center; }
189
 
190
- /* Log Out Link Style */
191
- .link-btn { background: transparent !important; border: none !important; box-shadow: none !important; color: #000 !important; text-decoration: underline; font-weight: bold !important; font-size: 12px !important; padding: 0 5px !important; min-width: auto !important; }
192
- .link-btn:hover { color: #cc0000 !important; }
193
-
194
- /* Login Button in Header */
195
- .header-login-btn { font-size: 13px !important; padding: 4px 12px !important; background-color: #f3f4f6 !important; color: #333 !important; border: 1px solid #ddd !important; border-radius: 15px !important; }
196
- .header-login-btn:hover { background-color: #e5e7eb !important; border-color: #ccc !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
 
198
  /* User Guide */
199
  .main-user-guide { border: none !important; background: transparent !important; box-shadow: none !important; }
@@ -236,7 +256,7 @@ with gr.Blocks(title="Clare – Hanbridge AI Teaching Assistant", css=CUSTOM_CSS
236
  user_name_state = gr.State("")
237
  user_id_state = gr.State("")
238
 
239
- # --- Header (Always Visible) ---
240
  with gr.Row(elem_classes="header-container"):
241
  # Left: Logo & Title
242
  with gr.Column(scale=2):
@@ -257,37 +277,15 @@ with gr.Blocks(title="Clare – Hanbridge AI Teaching Assistant", css=CUSTOM_CSS
257
  """
258
  )
259
 
260
- # Right: Hanbridge Logo & Dynamic Login Area
261
  with gr.Column(scale=1):
262
- # Top: Logo
263
  gr.HTML(
264
  f"""
265
- <div style="display:flex; justify-content:flex-end; margin-bottom: 8px;">
266
  <img src="{image_to_base64(HANBRIDGE_LOGO_PATH)}" style="height: 55px; object-fit: contain;">
267
  </div>
268
  """
269
  )
270
- # Bottom: Login UI Logic
271
- with gr.Row():
272
- with gr.Column(scale=1): pass # Spacer to push content right
273
-
274
- with gr.Column(scale=0, min_width=300):
275
-
276
- # 1. Default State: Login Button (Visible initially)
277
- login_start_btn = gr.Button("👤 Student Login", size="sm", elem_classes="header-login-btn")
278
-
279
- # 2. Input State: Inputs + Confirm (Hidden initially)
280
- with gr.Group(visible=False) as login_form_group:
281
- with gr.Row(elem_classes="no-gap"):
282
- name_input = gr.Textbox(placeholder="Name", show_label=False, container=False, scale=2, min_width=80)
283
- id_input = gr.Textbox(placeholder="ID", show_label=False, container=False, scale=2, min_width=80)
284
- login_confirm_btn = gr.Button("✅", size="sm", scale=1, min_width=40)
285
-
286
- # 3. Logged In State: Info + Logout (Hidden initially)
287
- with gr.Group(visible=False) as logged_in_group:
288
- with gr.Row(elem_classes="no-gap"):
289
- student_info_disp = gr.Markdown(value="", elem_id="student-info")
290
- logout_btn = gr.Button("Log Out", elem_classes="link-btn")
291
 
292
  # --- Main Layout ---
293
  with gr.Row():
@@ -385,39 +383,70 @@ with gr.Blocks(title="Clare – Hanbridge AI Teaching Assistant", css=CUSTOM_CSS
385
 
386
  # === Right Sidebar ===
387
  with gr.Column(scale=1, min_width=180):
388
- gr.HTML("<div style='height: 210px; width: 100%;'></div>") # Spacer
389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  gr.Markdown("### Actions")
391
  export_btn = gr.Button("Export Conversation", size="sm", elem_classes="action-btn")
392
  quiz_btn = gr.Button("Let's Try (Micro-Quiz)", size="sm", elem_classes="action-btn")
393
  summary_btn = gr.Button("Summarization", size="sm", elem_classes="action-btn")
394
 
 
395
  gr.Markdown("### Results")
396
  with gr.Group(elem_classes="result-box"):
397
  result_display = gr.Markdown(value="Results will appear here...", label="Generated Content")
398
 
399
- # ================== Logic: Login Flow ==================
400
 
401
- # 1. 点击 "Student Login" -> 显示输入框
402
- def show_login_form():
403
  return {
404
- login_start_btn: gr.update(visible=False),
405
- login_form_group: gr.update(visible=True)
 
406
  }
407
 
408
- login_start_btn.click(show_login_form, outputs=[login_start_btn, login_form_group])
409
 
410
- # 2. 点击 "✅" -> 确认登录 -> 显示信息
411
  def confirm_login(name, id_val):
412
  if not name or not id_val:
413
- # 简单校验,如果为空就不跳转 (实际可加提示)
414
- return gr.update(), gr.update(), gr.update(), gr.update()
 
 
 
 
 
 
 
 
415
 
416
- display_text = f"🎓 **{name}** ({id_val})"
417
  return {
418
- login_form_group: gr.update(visible=False),
419
- logged_in_group: gr.update(visible=True),
420
- student_info_disp: gr.update(value=display_text),
 
421
  user_name_state: name,
422
  user_id_state: id_val
423
  }
@@ -425,20 +454,22 @@ with gr.Blocks(title="Clare – Hanbridge AI Teaching Assistant", css=CUSTOM_CSS
425
  login_confirm_btn.click(
426
  confirm_login,
427
  inputs=[name_input, id_input],
428
- outputs=[login_form_group, logged_in_group, student_info_disp, user_name_state, user_id_state]
429
  )
430
 
431
- # 3. 点击 "Log Out" -> 重置回最初状态
432
  def logout():
433
  return {
434
- logged_in_group: gr.update(visible=False),
435
- login_start_btn: gr.update(visible=True),
 
436
  name_input: gr.update(value=""),
437
  id_input: gr.update(value=""),
438
- student_info_disp: gr.update(value="")
 
439
  }
440
 
441
- logout_btn.click(logout, outputs=[logged_in_group, login_start_btn, name_input, id_input, student_info_disp])
442
 
443
  # ================== Main App Logic ==================
444
 
 
31
  HANBRIDGE_LOGO_PATH = "hanbridge_logo.png"
32
  CLARE_LOGO_PATH = "clare_mascot.png"
33
  CLARE_RUN_PATH = "Clare_Run.png"
34
+ CLARE_READING_PATH = "clare_reading.png" # 请确保上传了这张图片
35
 
36
  # ================== Base64 Helper ==================
37
  def image_to_base64(image_path):
 
188
  /* --- Main Header --- */
189
  .header-container { padding: 10px 20px; background-color: #ffffff; border-bottom: 2px solid #f3f4f6; margin-bottom: 15px; display: flex; align-items: center; }
190
 
191
+ /* --- Sidebar Login Panel --- */
192
+ .login-panel {
193
+ background-color: #e5e7eb; /* 浅灰色背景 */
194
+ padding: 15px;
195
+ border-radius: 8px;
196
+ text-align: center;
197
+ margin-bottom: 20px;
198
+ }
199
+ .login-panel img {
200
+ display: block;
201
+ margin: 0 auto 10px auto;
202
+ height: 80px; /* 调整图片高度 */
203
+ object-fit: contain;
204
+ }
205
+ .login-main-btn {
206
+ background-color: #ffffff !important;
207
+ color: #000 !important;
208
+ border: 1px solid #000 !important;
209
+ font-weight: bold !important;
210
+ }
211
+ .logout-btn {
212
+ background-color: #6b2828 !important; /* 深红色背景 */
213
+ color: #fff !important;
214
+ border: none !important;
215
+ font-weight: bold !important;
216
+ }
217
 
218
  /* User Guide */
219
  .main-user-guide { border: none !important; background: transparent !important; box-shadow: none !important; }
 
256
  user_name_state = gr.State("")
257
  user_id_state = gr.State("")
258
 
259
+ # --- Header ---
260
  with gr.Row(elem_classes="header-container"):
261
  # Left: Logo & Title
262
  with gr.Column(scale=2):
 
277
  """
278
  )
279
 
280
+ # Right: Hanbridge Logo (Static)
281
  with gr.Column(scale=1):
 
282
  gr.HTML(
283
  f"""
284
+ <div style="display:flex; justify-content:flex-end; margin-bottom: 5px;">
285
  <img src="{image_to_base64(HANBRIDGE_LOGO_PATH)}" style="height: 55px; object-fit: contain;">
286
  </div>
287
  """
288
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
 
290
  # --- Main Layout ---
291
  with gr.Row():
 
383
 
384
  # === Right Sidebar ===
385
  with gr.Column(scale=1, min_width=180):
 
386
 
387
+ # --- New Login Panel (占用原来的 Spacer 空间) ---
388
+ with gr.Group(elem_classes="login-panel"):
389
+ # 图片始终显示
390
+ gr.HTML(f"<img src='{image_to_base64(CLARE_READING_PATH)}'>")
391
+
392
+ # 状态 1: 未登录 (显示 Login 按钮)
393
+ with gr.Group(visible=True) as login_state_1:
394
+ login_start_btn = gr.Button("Student Login", elem_classes="login-main-btn")
395
+
396
+ # 状态 2: 输入信息
397
+ with gr.Group(visible=False) as login_state_2:
398
+ name_input = gr.Textbox(label="Student Name", placeholder="Name", container=True)
399
+ id_input = gr.Textbox(label="Email/ID", placeholder="ID", container=True)
400
+ login_confirm_btn = gr.Button("Enter", variant="primary", size="sm")
401
+
402
+ # 状态 3: 已登录 (显示信息 + Logout)
403
+ with gr.Group(visible=False) as login_state_3:
404
+ # 使用 HTML 显示居中的加粗名字
405
+ student_info_html = gr.HTML()
406
+ logout_btn = gr.Button("Log out", elem_classes="logout-btn", size="sm")
407
+
408
+ # Actions
409
  gr.Markdown("### Actions")
410
  export_btn = gr.Button("Export Conversation", size="sm", elem_classes="action-btn")
411
  quiz_btn = gr.Button("Let's Try (Micro-Quiz)", size="sm", elem_classes="action-btn")
412
  summary_btn = gr.Button("Summarization", size="sm", elem_classes="action-btn")
413
 
414
+ # Results
415
  gr.Markdown("### Results")
416
  with gr.Group(elem_classes="result-box"):
417
  result_display = gr.Markdown(value="Results will appear here...", label="Generated Content")
418
 
419
+ # ================== Logic: Sidebar Login Flow ==================
420
 
421
+ # 1. Start Login -> Show Inputs
422
+ def show_inputs():
423
  return {
424
+ login_state_1: gr.update(visible=False),
425
+ login_state_2: gr.update(visible=True),
426
+ login_state_3: gr.update(visible=False)
427
  }
428
 
429
+ login_start_btn.click(show_inputs, outputs=[login_state_1, login_state_2, login_state_3])
430
 
431
+ # 2. Confirm Login -> Show Profile
432
  def confirm_login(name, id_val):
433
  if not name or not id_val:
434
+ # 简单验证,若为空则不跳转
435
+ return gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update()
436
+
437
+ # 构建居中的 HTML 信息
438
+ info_html = f"""
439
+ <div style="margin-bottom:10px;">
440
+ <div style="font-weight:bold; font-size:16px;">{name}</div>
441
+ <div style="color:#666; font-size:12px;">{id_val}</div>
442
+ </div>
443
+ """
444
 
 
445
  return {
446
+ login_state_1: gr.update(visible=False),
447
+ login_state_2: gr.update(visible=False),
448
+ login_state_3: gr.update(visible=True),
449
+ student_info_html: gr.update(value=info_html),
450
  user_name_state: name,
451
  user_id_state: id_val
452
  }
 
454
  login_confirm_btn.click(
455
  confirm_login,
456
  inputs=[name_input, id_input],
457
+ outputs=[login_state_1, login_state_2, login_state_3, student_info_html, user_name_state, user_id_state]
458
  )
459
 
460
+ # 3. Logout -> Reset
461
  def logout():
462
  return {
463
+ login_state_1: gr.update(visible=True),
464
+ login_state_2: gr.update(visible=False),
465
+ login_state_3: gr.update(visible=False),
466
  name_input: gr.update(value=""),
467
  id_input: gr.update(value=""),
468
+ user_name_state: "",
469
+ user_id_state: ""
470
  }
471
 
472
+ logout_btn.click(logout, outputs=[login_state_1, login_state_2, login_state_3, name_input, id_input, user_name_state, user_id_state])
473
 
474
  # ================== Main App Logic ==================
475