Lashtw commited on
Commit
9215d48
·
verified ·
1 Parent(s): 1f2360a

Upload 8 files

Browse files
Files changed (1) hide show
  1. src/views/StudentView.js +47 -8
src/views/StudentView.js CHANGED
@@ -1,4 +1,4 @@
1
- import { submitPrompt, getChallenges, startChallenge, getUserProgress, getPeerPrompts, resetProgress } from "../services/classroom.js";
2
 
3
  // Cache challenges locally
4
  let cachedChallenges = [];
@@ -357,16 +357,55 @@ window.loadPeerPrompts = async (challengeId) => {
357
  return;
358
  }
359
 
360
- container.innerHTML = prompts.map(p => `
 
 
 
 
361
  <div class="bg-gray-700/30 p-4 rounded-xl border border-gray-600">
362
- <div class="flex items-center space-x-2 mb-2">
363
- <div class="w-6 h-6 rounded-full bg-cyan-600 flex items-center justify-center text-xs font-bold text-white">
364
- ${p.nickname[0]}
 
 
 
 
365
  </div>
366
- <span class="font-bold text-cyan-300 text-sm">${p.nickname}</span>
367
- <span class="text-gray-500 text-xs ml-auto">${new Date(p.timestamp.seconds * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>
 
 
 
 
 
 
368
  </div>
369
  <p class="text-gray-300 font-mono text-sm bg-black/20 p-3 rounded-lg border border-gray-700/50 whitespace-pre-wrap">${p.prompt}</p>
370
  </div>
371
- `).join('');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
  };
 
1
+ import { submitPrompt, getChallenges, startChallenge, getUserProgress, getPeerPrompts, resetProgress, toggleLike, subscribeToNotifications, markNotificationRead } from "../services/classroom.js";
2
 
3
  // Cache challenges locally
4
  let cachedChallenges = [];
 
357
  return;
358
  }
359
 
360
+ container.innerHTML = prompts.map(p => {
361
+ const currentUserId = localStorage.getItem('vibecoding_user_id');
362
+ const isLiked = p.likedBy && p.likedBy.includes(currentUserId);
363
+
364
+ return `
365
  <div class="bg-gray-700/30 p-4 rounded-xl border border-gray-600">
366
+ <div class="flex items-center justify-between mb-2">
367
+ <div class="flex items-center space-x-2">
368
+ <div class="w-6 h-6 rounded-full bg-cyan-600 flex items-center justify-center text-xs font-bold text-white">
369
+ ${p.nickname[0]}
370
+ </div>
371
+ <span class="font-bold text-cyan-300 text-sm">${p.nickname}</span>
372
+ <span class="text-gray-500 text-xs">${new Date(p.timestamp.seconds * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>
373
  </div>
374
+
375
+ <button onclick="handleLike('${p.id}', '${p.userId}')"
376
+ class="flex items-center space-x-1 px-2 py-1 rounded-full transition-colors ${isLiked ? 'bg-pink-900/50 text-pink-400' : 'bg-gray-800 text-gray-400 hover:bg-gray-700'}">
377
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 ${isLiked ? 'fill-current' : 'none'}" viewBox="0 0 24 24" stroke="currentColor" fill="${isLiked ? 'currentColor' : 'none'}">
378
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
379
+ </svg>
380
+ <span class="text-xs font-bold">${p.likes}</span>
381
+ </button>
382
  </div>
383
  <p class="text-gray-300 font-mono text-sm bg-black/20 p-3 rounded-lg border border-gray-700/50 whitespace-pre-wrap">${p.prompt}</p>
384
  </div>
385
+ `}).join('');
386
+
387
+ // Attach challenge title for notification context
388
+ window.currentPeerChallengeTitle = document.querySelector(`#peer-challenge-select option[value="${challengeId}"]`).text;
389
+ };
390
+
391
+ // Like Handler
392
+ window.handleLike = async (progressId, targetUserId) => {
393
+ const userId = localStorage.getItem('vibecoding_user_id');
394
+ const nickname = localStorage.getItem('vibecoding_nickname');
395
+ const challengeTitle = window.currentPeerChallengeTitle || '挑戰';
396
+
397
+ // Optimistic UI update could go here, but for simplicity let's re-load or just fire and forget (the view won't update until reload currently)
398
+ // To make it responsive, we should probably manually toggle the class on the button immediately.
399
+ // For now, let's just call service and reload the list to see updated count.
400
+
401
+ // Better UX: Find button and toggle 'processing' state?
402
+ // Let's just reload the list for data consistency.
403
+ const { toggleLike } = await import("../services/classroom.js");
404
+ await toggleLike(progressId, userId, nickname, targetUserId, challengeTitle);
405
+
406
+ // Reload to refresh count
407
+ const select = document.getElementById('peer-challenge-select');
408
+ if (select && select.value) {
409
+ loadPeerPrompts(select.value);
410
+ }
411
  };