cdechoch commited on
Commit
83c7b7f
·
verified ·
1 Parent(s): 4b68be7

Update player.html

Browse files
Files changed (1) hide show
  1. player.html +31 -8
player.html CHANGED
@@ -25,7 +25,12 @@
25
  .player-team a { color: #f97316; text-decoration: none; }
26
  .player-team a:hover { text-decoration: underline; }
27
  .mention-count-header { font-size: 48px; font-weight: bold; color: #f97316; }
28
- .mention-count-label { font-size: 14px; color: #888; text-transform: uppercase; }
 
 
 
 
 
29
  .section-title { font-size: 18px; font-weight: 600; color: #333; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 2px solid #f97316; }
30
  .mentions-list { display: flex; flex-direction: column; gap: 15px; margin-bottom: 30px; }
31
  .mention-card { background: white; border-radius: 12px; padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
@@ -65,8 +70,13 @@
65
  <div class="player-header">
66
  <div class="player-name" id="playerName">Loading...</div>
67
  <div class="player-team" id="playerTeam"></div>
68
- <div class="mention-count-header" id="totalMentions">-</div>
69
- <div class="mention-count-label">mentions</div>
 
 
 
 
 
70
  </div>
71
  <div class="section-title">Recent Mentions</div>
72
  <div class="mentions-list" id="mentionsList"><div class="loading"><div class="spinner"></div><p>Loading...</p></div></div>
@@ -111,9 +121,12 @@
111
  function processText(text) {
112
  if (!text) return '';
113
  let escaped = escapeHtml(text);
114
- // Match URLs with or without https://
115
- escaped = escaped.replace(/(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/g, '<a href="$1" target="_blank">$1</a>');
116
- escaped = escaped.replace(/(?<![:\/])(www\.[^\s<]+[^<.,:;"')\]\s])/g, '<a href="https://$1" target="_blank">$1</a>');
 
 
 
117
  for (const player of allPlayers) {
118
  if (player === playerName) continue;
119
  const regex = new RegExp(`\\b(${player.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})\\b`, 'gi');
@@ -141,11 +154,21 @@
141
  if (info.team) document.getElementById('playerTeam').innerHTML = `<a href="/team/${encodeURIComponent(info.team)}">${info.team}</a>`;
142
  if (info.teammates?.length) document.getElementById('relatedGrid').innerHTML = info.teammates.map(t => `<a href="/player/${encodeURIComponent(t)}" class="related-link">${t}</a>`).join('');
143
  else document.getElementById('relatedGrid').innerHTML = '<p style="color:#888">No teammates</p>';
144
- } catch (e) {}
 
 
 
 
 
 
 
 
 
 
 
145
 
146
  try {
147
  const mentions = await (await fetch(`/api/mentions/${encodeURIComponent(playerName)}?limit=50`)).json();
148
- document.getElementById('totalMentions').textContent = mentions.length;
149
  if (!mentions.length) { document.getElementById('mentionsList').innerHTML = '<div class="empty-state"><h3>No mentions found</h3></div>'; return; }
150
  document.getElementById('mentionsList').innerHTML = mentions.map(m => {
151
  const avatarUrl = m.author_avatar || 'https://cdn.bsky.app/img/avatar/plain/did:plc:default/default@jpeg';
 
25
  .player-team a { color: #f97316; text-decoration: none; }
26
  .player-team a:hover { text-decoration: underline; }
27
  .mention-count-header { font-size: 48px; font-weight: bold; color: #f97316; }
28
+ .mention-count-label { font-size: 14px; color: #888; text-transform: uppercase; margin-bottom: 20px; }
29
+ .period-stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; margin-top: 15px; }
30
+ .period-stat { background: #f8f9fa; border-radius: 8px; padding: 12px; text-align: center; }
31
+ .period-label { font-size: 12px; color: #888; font-weight: 600; margin-bottom: 4px; }
32
+ .period-mentions { font-size: 20px; font-weight: bold; color: #f97316; }
33
+ .period-rank { font-size: 11px; color: #666; margin-top: 2px; }
34
  .section-title { font-size: 18px; font-weight: 600; color: #333; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 2px solid #f97316; }
35
  .mentions-list { display: flex; flex-direction: column; gap: 15px; margin-bottom: 30px; }
36
  .mention-card { background: white; border-radius: 12px; padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
 
70
  <div class="player-header">
71
  <div class="player-name" id="playerName">Loading...</div>
72
  <div class="player-team" id="playerTeam"></div>
73
+ <div class="period-stats" id="periodStats">
74
+ <div class="period-stat"><div class="period-label">6h</div><div class="period-mentions">-</div><div class="period-rank"></div></div>
75
+ <div class="period-stat"><div class="period-label">12h</div><div class="period-mentions">-</div><div class="period-rank"></div></div>
76
+ <div class="period-stat"><div class="period-label">24h</div><div class="period-mentions">-</div><div class="period-rank"></div></div>
77
+ <div class="period-stat"><div class="period-label">48h</div><div class="period-mentions">-</div><div class="period-rank"></div></div>
78
+ <div class="period-stat"><div class="period-label">7d</div><div class="period-mentions">-</div><div class="period-rank"></div></div>
79
+ </div>
80
  </div>
81
  <div class="section-title">Recent Mentions</div>
82
  <div class="mentions-list" id="mentionsList"><div class="loading"><div class="spinner"></div><p>Loading...</p></div></div>
 
121
  function processText(text) {
122
  if (!text) return '';
123
  let escaped = escapeHtml(text);
124
+ // Match URLs - https://, http://, and common short domains
125
+ escaped = escaped.replace(/(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/gi, '<a href="$1" target="_blank">$1</a>');
126
+ // Match youtu.be, bit.ly, etc without protocol
127
+ escaped = escaped.replace(/(?<![\/\w])((?:youtu\.be|bit\.ly|t\.co|tinyurl\.com|goo\.gl)\/[^\s<]+[^<.,:;"')\]\s])/gi, '<a href="https://$1" target="_blank">$1</a>');
128
+ // Match www. URLs
129
+ escaped = escaped.replace(/(?<![\/\w])(www\.[^\s<]+[^<.,:;"')\]\s])/gi, '<a href="https://$1" target="_blank">$1</a>');
130
  for (const player of allPlayers) {
131
  if (player === playerName) continue;
132
  const regex = new RegExp(`\\b(${player.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})\\b`, 'gi');
 
154
  if (info.team) document.getElementById('playerTeam').innerHTML = `<a href="/team/${encodeURIComponent(info.team)}">${info.team}</a>`;
155
  if (info.teammates?.length) document.getElementById('relatedGrid').innerHTML = info.teammates.map(t => `<a href="/player/${encodeURIComponent(t)}" class="related-link">${t}</a>`).join('');
156
  else document.getElementById('relatedGrid').innerHTML = '<p style="color:#888">No teammates</p>';
157
+
158
+ // Populate period stats
159
+ if (info.period_stats) {
160
+ document.getElementById('periodStats').innerHTML = info.period_stats.map(p => `
161
+ <div class="period-stat">
162
+ <div class="period-label">${p.label}</div>
163
+ <div class="period-mentions">${p.mentions}</div>
164
+ <div class="period-rank">${p.rank ? '#' + p.rank : '-'}</div>
165
+ </div>
166
+ `).join('');
167
+ }
168
+ } catch (e) { console.error(e); }
169
 
170
  try {
171
  const mentions = await (await fetch(`/api/mentions/${encodeURIComponent(playerName)}?limit=50`)).json();
 
172
  if (!mentions.length) { document.getElementById('mentionsList').innerHTML = '<div class="empty-state"><h3>No mentions found</h3></div>'; return; }
173
  document.getElementById('mentionsList').innerHTML = mentions.map(m => {
174
  const avatarUrl = m.author_avatar || 'https://cdn.bsky.app/img/avatar/plain/did:plc:default/default@jpeg';