Kerikim commited on
Commit
04ada98
·
1 Parent(s): 44b5561

elkay frontend game leaderboard

Browse files
Files changed (1) hide show
  1. phase/Student_view/game.py +39 -62
phase/Student_view/game.py CHANGED
@@ -124,19 +124,13 @@ def render_leaderboard(leaderboard):
124
  st.markdown(html, unsafe_allow_html=True)
125
 
126
  def _load_leaderboard(user_id: int, limit: int = 10) -> list[dict]:
127
- """
128
- Returns rows shaped for render_leaderboard():
129
- [{"rank": int|"You", "name": str, "level": int, "xp": int, "user_id": int}, ...]
130
- - If DISABLE_DB=1, fetch from backend via utils.api.
131
- - If local DB is enabled, use utils.db.
132
- """
133
  you_name = (st.session_state.get("user") or {}).get("name") or "You"
134
  class_id = st.session_state.get("current_class_id")
135
  rows: list[dict] = []
136
 
137
  try:
138
  if USE_LOCAL_DB:
139
- # Local DB path
140
  if not class_id and hasattr(dbapi, "list_classes_for_student"):
141
  classes = dbapi.list_classes_for_student(user_id) or []
142
  if classes:
@@ -148,19 +142,17 @@ def _load_leaderboard(user_id: int, limit: int = 10) -> list[dict]:
148
  elif hasattr(dbapi, "leaderboard_global"):
149
  rows = dbapi.leaderboard_global(limit=limit) or []
150
  elif class_id and hasattr(dbapi, "class_student_metrics"):
151
- # Build from metrics if no leaderboard helper
152
  metrics = dbapi.class_student_metrics(class_id) or []
153
- rows = [
154
- {
155
- "user_id": m.get("student_id"),
156
- "name": m.get("name") or m.get("email") or "Student",
157
- "xp": int(m.get("total_xp", 0)),
158
- "level": dbapi.level_from_xp(int(m.get("total_xp", 0))),
159
- }
160
- for m in metrics
161
- ]
162
  else:
163
- # Backend API path
 
164
  if not class_id:
165
  try:
166
  classes = api.list_classes_for_student(user_id) or []
@@ -171,56 +163,44 @@ def _load_leaderboard(user_id: int, limit: int = 10) -> list[dict]:
171
  st.session_state.current_class_id = class_id
172
 
173
  if class_id:
174
- # Use per-class metrics from backend and derive leaderboard
175
  try:
176
- metrics = api.class_student_metrics(class_id) or []
177
  except Exception:
178
- metrics = []
179
- rows = [
180
- {
181
- "user_id": m.get("student_id"),
182
- "name": m.get("name") or m.get("email") or "Student",
183
- "xp": int(m.get("total_xp", 0)),
184
- # if backend does not send level, compute from XP
185
- "level": (int(m.get("level")) if "level" in m
186
- else 1 + int(m.get("total_xp", 0)) // 500),
187
- }
188
- for m in metrics
189
- ]
 
 
 
 
 
 
190
  else:
191
- # No class. At least show the current user by calling /students/{id}/stats
192
  try:
193
- stats = api.user_stats(user_id) or {}
194
  except Exception:
195
- stats = {}
196
- rows = [{
197
- "user_id": user_id,
198
- "name": you_name,
199
- "xp": int(stats.get("xp", 0)),
200
- "level": int(stats.get("level", 1)),
201
- }]
202
  except Exception:
203
- # Silent fallback, do not spam a yellow warning box
204
  rows = []
205
 
206
- # Ensure current user is present
207
  if not any(r.get("user_id") == user_id for r in rows):
208
- # pull stats from whichever path is available
209
- if USE_LOCAL_DB:
210
- try:
211
- s = dbapi.user_xp_and_level(user_id) or {}
212
- you_xp = int(s.get("xp", 0)); you_lvl = int(s.get("level", 1))
213
- except Exception:
214
- you_xp, you_lvl = 0, 1
215
- else:
216
- try:
217
- s = api.user_stats(user_id) or {}
218
- you_xp = int(s.get("xp", 0)); you_lvl = int(s.get("level", 1))
219
- except Exception:
220
- you_xp, you_lvl = 0, 1
221
- rows.append({"user_id": user_id, "name": you_name, "xp": you_xp, "level": you_lvl})
222
 
223
- # Sort by XP desc and rank
224
  rows.sort(key=lambda r: int(r.get("xp", 0)), reverse=True)
225
  ranked = []
226
  for i, r in enumerate(rows, start=1):
@@ -231,20 +211,17 @@ def _load_leaderboard(user_id: int, limit: int = 10) -> list[dict]:
231
  "level": int(r["level"]),
232
  "xp": int(r["xp"]),
233
  })
234
-
235
- # Mark "You"
236
  for r in ranked:
237
  if r["user_id"] == user_id:
238
  r["rank"] = "You"
239
  break
240
-
241
- # Put "You" at the top visually
242
  you = [r for r in ranked if r["rank"] == "You"]
243
  others = [r for r in ranked if r["rank"] != "You"]
244
  return (you + others)[:limit]
245
 
246
 
247
 
 
248
  # --- MAIN GAMES HUB & ROUTER ---
249
  def show_games():
250
  load_css(os.path.join("assets", "styles.css"))
 
124
  st.markdown(html, unsafe_allow_html=True)
125
 
126
  def _load_leaderboard(user_id: int, limit: int = 10) -> list[dict]:
 
 
 
 
 
 
127
  you_name = (st.session_state.get("user") or {}).get("name") or "You"
128
  class_id = st.session_state.get("current_class_id")
129
  rows: list[dict] = []
130
 
131
  try:
132
  if USE_LOCAL_DB:
133
+ # ---------- local DB path ----------
134
  if not class_id and hasattr(dbapi, "list_classes_for_student"):
135
  classes = dbapi.list_classes_for_student(user_id) or []
136
  if classes:
 
142
  elif hasattr(dbapi, "leaderboard_global"):
143
  rows = dbapi.leaderboard_global(limit=limit) or []
144
  elif class_id and hasattr(dbapi, "class_student_metrics"):
 
145
  metrics = dbapi.class_student_metrics(class_id) or []
146
+ rows = [{
147
+ "user_id": m.get("student_id"),
148
+ "name": m.get("name") or m.get("email") or "Student",
149
+ "xp": int(m.get("total_xp", 0)),
150
+ "level": dbapi.level_from_xp(int(m.get("total_xp", 0))),
151
+ } for m in metrics]
152
+
 
 
153
  else:
154
+ # ---------- backend API path (DISABLE_DB=1) ----------
155
+ # 1) pick a class for the logged-in student
156
  if not class_id:
157
  try:
158
  classes = api.list_classes_for_student(user_id) or []
 
163
  st.session_state.current_class_id = class_id
164
 
165
  if class_id:
166
+ # 2) get roster
167
  try:
168
+ roster = api.list_students_in_class(class_id) or []
169
  except Exception:
170
+ roster = []
171
+
172
+ # 3) for each student, pull stats (XP/level)
173
+ rows = []
174
+ for s in roster:
175
+ sid = s.get("user_id") or s.get("student_id")
176
+ if not sid:
177
+ continue
178
+ try:
179
+ stt = api.user_stats(int(sid)) or {}
180
+ except Exception:
181
+ stt = {}
182
+ rows.append({
183
+ "user_id": int(sid),
184
+ "name": s.get("name") or s.get("email") or "Student",
185
+ "xp": int(stt.get("xp", 0)),
186
+ "level": int(stt.get("level", 1)),
187
+ })
188
  else:
189
+ # No class available; at least show the current user
190
  try:
191
+ s = api.user_stats(user_id) or {}
192
  except Exception:
193
+ s = {}
194
+ rows = [{"user_id": user_id, "name": you_name,
195
+ "xp": int(s.get("xp", 0)), "level": int(s.get("level", 1))}]
 
 
 
 
196
  except Exception:
 
197
  rows = []
198
 
199
+ # Ensure YOU is present
200
  if not any(r.get("user_id") == user_id for r in rows):
201
+ rows.append({"user_id": user_id, "name": you_name, "xp": 0, "level": 1})
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
+ # Rank, mark YOU, put YOU first
204
  rows.sort(key=lambda r: int(r.get("xp", 0)), reverse=True)
205
  ranked = []
206
  for i, r in enumerate(rows, start=1):
 
211
  "level": int(r["level"]),
212
  "xp": int(r["xp"]),
213
  })
 
 
214
  for r in ranked:
215
  if r["user_id"] == user_id:
216
  r["rank"] = "You"
217
  break
 
 
218
  you = [r for r in ranked if r["rank"] == "You"]
219
  others = [r for r in ranked if r["rank"] != "You"]
220
  return (you + others)[:limit]
221
 
222
 
223
 
224
+
225
  # --- MAIN GAMES HUB & ROUTER ---
226
  def show_games():
227
  load_css(os.path.join("assets", "styles.css"))