Kerikim commited on
Commit
5e3abcf
·
1 Parent(s): c378c1e

elkay frontend game xp

Browse files
Files changed (2) hide show
  1. dashboards/student_db.py +28 -24
  2. phase/Student_view/game.py +30 -30
dashboards/student_db.py CHANGED
@@ -14,6 +14,17 @@ def load_css(file_name: str):
14
  except FileNotFoundError:
15
  st.warning("⚠️ Stylesheet not found. Please ensure 'assets/styles.css' exists.")
16
 
 
 
 
 
 
 
 
 
 
 
 
17
  def show_student_dashboard():
18
  # Load CSS
19
  css_path = os.path.join("assets", "styles.css")
@@ -139,36 +150,29 @@ def show_student_dashboard():
139
  st.write("")
140
 
141
  # --- XP Bar ---
142
- xp = int(stats.get("xp", 0))
143
- level = int(stats.get("level", 1))
144
- study_streak = int(stats.get("streak", 0))
145
-
146
- # prefer server-provided per-level fields
147
- into = int(stats.get("into", -1))
148
- need = int(stats.get("need", -1))
149
-
150
- # fallback if backend hasn't been updated to include into/need yet
151
- if into < 0 or need <= 0:
152
- base = 500
153
- level = max(1, xp // base + 1)
154
- start = (level - 1) * base
155
- into = xp - start
156
- need = base
157
- if into == need:
158
- level += 1
159
- into = 0
160
-
161
- pct = 0 if need <= 0 else min(100, int(round((into / need) * 100)))
162
 
163
  st.markdown(
164
  f"""
165
  <div class="xp-card">
166
  <span class="xp-level">Level {level}</span>
167
  <span class="xp-text">{into:,} / {need:,} XP</span>
168
- <div class="xp-bar">
169
- <div class="xp-fill" style="width: {pct}%;"></div>
170
- </div>
171
- <div class="xp-total">Total XP: {xp:,}</div>
172
  </div>
173
  """,
174
  unsafe_allow_html=True
 
14
  except FileNotFoundError:
15
  st.warning("⚠️ Stylesheet not found. Please ensure 'assets/styles.css' exists.")
16
 
17
+ def _level_progress(total_xp: int, base: int = 500):
18
+ xp = int(max(0, total_xp))
19
+ level = max(1, xp // base + 1)
20
+ into = xp - (level - 1) * base
21
+ need = base
22
+ if into == need: # exact boundary
23
+ level += 1
24
+ into = 0
25
+ pct = int(round(100 * into / need)) if need else 0
26
+ return level, into, need, pct
27
+
28
  def show_student_dashboard():
29
  # Load CSS
30
  css_path = os.path.join("assets", "styles.css")
 
150
  st.write("")
151
 
152
  # --- XP Bar ---
153
+ # --- XP Bar (live, per-level) ---
154
+ total_xp = int(stats.get("xp", 0))
155
+ level_api = int(stats.get("level", 1))
156
+
157
+ # prefer server fields if present
158
+ into = stats.get("into")
159
+ need = stats.get("need")
160
+
161
+ if isinstance(into, (int, float)) and isinstance(need, (int, float)) and need > 0:
162
+ level = level_api
163
+ into = int(into)
164
+ need = int(need)
165
+ pct = min(100, int(round(100 * into / need)))
166
+ else:
167
+ level, into, need, pct = _level_progress(total_xp)
 
 
 
 
 
168
 
169
  st.markdown(
170
  f"""
171
  <div class="xp-card">
172
  <span class="xp-level">Level {level}</span>
173
  <span class="xp-text">{into:,} / {need:,} XP</span>
174
+ <div class="xp-bar"><div class="xp-fill" style="width:{pct}%;"></div></div>
175
+ <div class="xp-total">Total XP: {total_xp:,}</div>
 
 
176
  </div>
177
  """,
178
  unsafe_allow_html=True
phase/Student_view/game.py CHANGED
@@ -16,6 +16,16 @@ def load_css(file_name: str):
16
 
17
  st.session_state.setdefault("current_game", None)
18
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  # --- GAME RENDERERS ---
21
  def _render_budget_builder():
@@ -259,45 +269,36 @@ def show_games():
259
  # pull live XP/level
260
  user_id = st.session_state.user["user_id"]
261
 
262
- # Prefer local DB only if enabled. Otherwise call backend.
263
- if USE_LOCAL_DB and hasattr(dbapi, "user_xp_and_level"):
264
- stats = dbapi.user_xp_and_level(user_id) # {'xp', 'level', 'streak', maybe 'into','need'}
265
- else:
266
- try:
267
- stats = api.user_stats(user_id) # backend /students/{id}/stats
268
- except Exception as e:
269
- # hard fallback so the page still renders
270
- stats = {"xp": int(st.session_state.get("xp", 0)), "level": 1, "streak": 0}
271
 
272
  total_xp = int(stats.get("xp", 0))
273
- level = int(stats.get("level", 1))
274
- st.session_state.xp = total_xp
275
  st.session_state.streak = int(stats.get("streak", 0))
276
 
277
- # Use server-provided per-level values when available
278
  into = stats.get("into")
279
  need = stats.get("need")
280
 
281
- # Fallback if backend has not been updated yet
282
- if into is None or need in (None, 0):
283
- base = 500
284
- level = max(1, total_xp // base + 1)
285
- start = (level - 1) * base
286
- into = total_xp - start
287
- need = base
288
- if into == need:
289
- level += 1
290
- into = 0
291
-
292
- into = int(max(0, into))
293
- need = int(max(1, need))
294
- progress_pct = min(100, int(round((into / need) * 100)))
295
-
296
- st.write(f"Level {level} Experience Points")
297
  st.markdown(f"""
298
  <div style="background:#e0e0e0;border-radius:12px;padding:3px;width:100%;">
299
  <div style="
300
- width:{progress_pct}%;
301
  background:linear-gradient(135deg,#22c55e,#059669);
302
  height:24px;border-radius:10px;text-align:right;
303
  color:white;font-weight:bold;padding-right:8px;line-height:24px;">
@@ -309,7 +310,6 @@ def show_games():
309
 
310
 
311
 
312
-
313
  st.markdown("---")
314
 
315
  # Game list
 
16
 
17
  st.session_state.setdefault("current_game", None)
18
 
19
+ def _level_progress(total_xp: int, base: int = 500):
20
+ xp = int(max(0, total_xp))
21
+ level = max(1, xp // base + 1)
22
+ into = xp - (level - 1) * base
23
+ need = base
24
+ if into == need:
25
+ level += 1
26
+ into = 0
27
+ pct = int(round(100 * into / need)) if need else 0
28
+ return level, into, need, pct
29
 
30
  # --- GAME RENDERERS ---
31
  def _render_budget_builder():
 
269
  # pull live XP/level
270
  user_id = st.session_state.user["user_id"]
271
 
272
+ # DB if enabled, else backend
273
+ try:
274
+ if USE_LOCAL_DB and hasattr(dbapi, "user_xp_and_level"):
275
+ stats = dbapi.user_xp_and_level(user_id)
276
+ else:
277
+ stats = api.user_stats(user_id) # /students/{id}/stats
278
+ except Exception:
279
+ stats = {"xp": int(st.session_state.get("xp", 0)), "level": 1, "streak": 0}
 
280
 
281
  total_xp = int(stats.get("xp", 0))
282
+ level_api = int(stats.get("level", 1))
283
+ st.session_state.xp = total_xp
284
  st.session_state.streak = int(stats.get("streak", 0))
285
 
 
286
  into = stats.get("into")
287
  need = stats.get("need")
288
 
289
+ if isinstance(into, (int, float)) and isinstance(need, (int, float)) and need > 0:
290
+ level = level_api
291
+ into = int(into)
292
+ need = int(need)
293
+ pct = min(100, int(round(100 * into / need)))
294
+ else:
295
+ level, into, need, pct = _level_progress(total_xp)
296
+
297
+ st.write(f"Level {level} Experience Points")
 
 
 
 
 
 
 
298
  st.markdown(f"""
299
  <div style="background:#e0e0e0;border-radius:12px;padding:3px;width:100%;">
300
  <div style="
301
+ width:{pct}%;
302
  background:linear-gradient(135deg,#22c55e,#059669);
303
  height:24px;border-radius:10px;text-align:right;
304
  color:white;font-weight:bold;padding-right:8px;line-height:24px;">
 
310
 
311
 
312
 
 
313
  st.markdown("---")
314
 
315
  # Game list