|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | +<meta charset="UTF-8" /> |
| 5 | +<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| 6 | +<title>dev_profile</title> |
| 7 | +<meta id="og-title" property="og:title" content="dev_profile" /> |
| 8 | +<meta id="og-desc" property="og:description" content="Developer profile" /> |
| 9 | +<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Syne:wght@400;600;800&display=swap" rel="stylesheet" /> |
| 10 | +<style> |
| 11 | +*,*::before,*::after{box-sizing:border-box;margin:0;padding:0} |
| 12 | +:root{ |
| 13 | + --bg:#0a0c10;--surface:#10141c;--surface2:#161b26;--border:#1e2535; |
| 14 | + --green:#00ff88;--amber:#f5a623;--red:#ff4455;--blue:#4a9eff; |
| 15 | + --text:#e2e8f0;--text-muted:#64748b;--text-dim:#334155; |
| 16 | + --font-mono:'JetBrains Mono',monospace;--font-display:'Syne',sans-serif; |
| 17 | +} |
| 18 | +body{background:var(--bg);color:var(--text);font-family:var(--font-mono);font-size:13px;min-height:100vh} |
| 19 | +body::before{content:'';position:fixed;inset:0;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,255,136,0.01) 2px,rgba(0,255,136,0.01) 4px);pointer-events:none;z-index:0} |
| 20 | + |
| 21 | +.page{max-width:860px;margin:0 auto;padding:40px 24px;position:relative;z-index:1} |
| 22 | + |
| 23 | +/* states */ |
| 24 | +#loading,#not-found,#search-screen{display:none;min-height:60vh;align-items:center;justify-content:center;flex-direction:column;gap:14px;text-align:center} |
| 25 | +#loading.active,#not-found.active,#search-screen.active{display:flex} |
| 26 | +#profile-content{display:none} |
| 27 | +#profile-content.active{display:block} |
| 28 | + |
| 29 | +.loader-bar{width:180px;height:2px;background:var(--border);overflow:hidden} |
| 30 | +.loader-bar::after{content:'';display:block;height:100%;width:40%;background:var(--green);animation:slide 1s ease-in-out infinite alternate} |
| 31 | +@keyframes slide{from{transform:translateX(-100%)}to{transform:translateX(350%)}} |
| 32 | +.loader-text{color:var(--green);font-size:11px;letter-spacing:1px} |
| 33 | +.nf-code{font-family:var(--font-display);font-size:72px;font-weight:800;color:var(--green);opacity:.15;line-height:1} |
| 34 | +.nf-msg{font-size:13px;color:var(--text-muted)} |
| 35 | + |
| 36 | +/* search */ |
| 37 | +.search-box{border:1px solid var(--green);padding:40px 48px;width:440px;position:relative;background:rgba(0,255,136,0.02)} |
| 38 | +.s-corner{position:absolute;width:12px;height:12px;border-color:var(--green);border-style:solid} |
| 39 | +.s-corner.tl{top:-1px;left:-1px;border-width:2px 0 0 2px} |
| 40 | +.s-corner.tr{top:-1px;right:-1px;border-width:2px 2px 0 0} |
| 41 | +.s-corner.bl{bottom:-1px;left:-1px;border-width:0 0 2px 2px} |
| 42 | +.s-corner.br{bottom:-1px;right:-1px;border-width:0 2px 2px 0} |
| 43 | +.s-title{font-family:var(--font-display);font-size:26px;font-weight:800;color:var(--green);margin-bottom:4px} |
| 44 | +.s-sub{font-size:11px;color:var(--text-muted);margin-bottom:24px} |
| 45 | +.s-row{display:flex;gap:8px} |
| 46 | +.s-input{flex:1;background:var(--surface2);border:1px solid var(--border);color:var(--text);font-family:var(--font-mono);font-size:13px;padding:10px 13px;outline:none;transition:border-color .2s} |
| 47 | +.s-input:focus{border-color:var(--green)} |
| 48 | +.s-btn{background:var(--green);color:#000;border:none;font-family:var(--font-mono);font-size:12px;font-weight:700;padding:0 18px;cursor:pointer;letter-spacing:.5px;transition:opacity .2s} |
| 49 | +.s-btn:hover{opacity:.85} |
| 50 | + |
| 51 | +/* profile header */ |
| 52 | +.profile-header{display:flex;align-items:flex-start;gap:24px;margin-bottom:28px;padding-bottom:24px;border-bottom:1px solid var(--border)} |
| 53 | +.avatar{width:80px;height:80px;border-radius:50%;border:2px solid var(--green);overflow:hidden;flex-shrink:0} |
| 54 | +.avatar img{width:100%;height:100%;object-fit:cover} |
| 55 | +.profile-info{flex:1;min-width:0} |
| 56 | +.profile-name{font-family:var(--font-display);font-size:26px;font-weight:800;color:var(--green);line-height:1.1;margin-bottom:2px} |
| 57 | +.profile-login{font-size:12px;color:var(--text-muted);margin-bottom:8px;display:flex;align-items:center;gap:6px} |
| 58 | +.online-dot{width:6px;height:6px;background:var(--green);border-radius:50%;display:inline-block;animation:pulse 2s infinite} |
| 59 | +@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}} |
| 60 | +.profile-bio{font-size:12px;color:var(--text);line-height:1.65;margin-bottom:10px;max-width:500px} |
| 61 | +.profile-meta{display:flex;gap:14px;flex-wrap:wrap} |
| 62 | +.meta-item{font-size:11px;color:var(--text-muted)} |
| 63 | +.meta-item a{color:var(--blue);text-decoration:none} |
| 64 | +.profile-actions{display:flex;gap:8px;flex-shrink:0;align-items:flex-start} |
| 65 | +.btn-gh{background:var(--green);color:#000;border:none;font-family:var(--font-mono);font-size:11px;font-weight:700;padding:8px 14px;cursor:pointer;letter-spacing:.5px;text-transform:uppercase;text-decoration:none;display:inline-block;transition:opacity .2s} |
| 66 | +.btn-gh:hover{opacity:.85} |
| 67 | +.btn-copy{background:transparent;border:1px solid var(--border);color:var(--text-muted);font-family:var(--font-mono);font-size:11px;padding:8px 14px;cursor:pointer;letter-spacing:.5px;text-transform:uppercase;transition:all .2s} |
| 68 | +.btn-copy:hover{border-color:var(--green);color:var(--green)} |
| 69 | + |
| 70 | +/* stat grid */ |
| 71 | +.stat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:14px} |
| 72 | +.stat-card{background:var(--surface2);border:1px solid var(--border);padding:14px;text-align:center} |
| 73 | +.stat-val{font-family:var(--font-display);font-size:26px;font-weight:800;color:var(--green);display:block;line-height:1} |
| 74 | +.stat-label{font-size:10px;text-transform:uppercase;letter-spacing:1px;color:var(--text-muted);margin-top:4px;display:block} |
| 75 | + |
| 76 | +/* section */ |
| 77 | +.section{background:var(--surface);border:1px solid var(--border);padding:20px;margin-bottom:14px;position:relative} |
| 78 | +.section::before{content:'';position:absolute;top:0;left:0;width:3px;height:100%;background:var(--green);opacity:.5} |
| 79 | +.section-title{font-size:10px;text-transform:uppercase;letter-spacing:1.5px;color:var(--text-muted);margin-bottom:14px;display:flex;align-items:center;gap:6px} |
| 80 | +.section-icon{width:5px;height:5px;background:var(--green);display:inline-block} |
| 81 | + |
| 82 | +/* lang bars */ |
| 83 | +.lang-bar-item{display:flex;align-items:center;gap:10px;margin-bottom:10px} |
| 84 | +.lang-name{font-size:11px;color:var(--text-muted);width:80px;flex-shrink:0} |
| 85 | +.lang-bar-bg{flex:1;height:5px;background:var(--surface2)} |
| 86 | +.lang-bar-fill{height:100%;transition:width 1.2s ease} |
| 87 | +.lang-pct{font-size:11px;color:var(--text-muted);width:34px;text-align:right;flex-shrink:0} |
| 88 | + |
| 89 | +/* repo grid */ |
| 90 | +.repo-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px} |
| 91 | +.repo-card{background:var(--surface2);border:1px solid var(--border);padding:14px;cursor:pointer;transition:border-color .2s;text-decoration:none;display:block} |
| 92 | +.repo-card:hover{border-color:var(--green)} |
| 93 | +.repo-name{font-size:12px;color:var(--blue);font-weight:500;margin-bottom:4px} |
| 94 | +.repo-desc{font-size:11px;color:var(--text-muted);line-height:1.5;margin-bottom:8px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2em} |
| 95 | +.repo-meta{display:flex;align-items:center;gap:10px;font-size:11px;color:var(--text-muted)} |
| 96 | +.lang-dot{width:7px;height:7px;border-radius:50%;display:inline-block;margin-right:3px} |
| 97 | +.stars{color:var(--amber)} |
| 98 | + |
| 99 | +/* heatmap */ |
| 100 | +.heatmap-wrap{overflow-x:auto;padding-bottom:4px} |
| 101 | +.heatmap-grid{display:flex;gap:3px;min-width:fit-content} |
| 102 | +.heatmap-week{display:flex;flex-direction:column;gap:3px} |
| 103 | +.heatmap-cell{width:11px;height:11px;border-radius:2px;flex-shrink:0} |
| 104 | +.heatmap-cell[data-count="0"]{background:#111720} |
| 105 | +.heatmap-cell[data-level="1"]{background:#004422} |
| 106 | +.heatmap-cell[data-level="2"]{background:#006633} |
| 107 | +.heatmap-cell[data-level="3"]{background:#00aa55} |
| 108 | +.heatmap-cell[data-level="4"]{background:#00ff88} |
| 109 | +.heatmap-footer{display:flex;align-items:center;gap:8px;margin-top:8px;font-size:10px;color:var(--text-muted)} |
| 110 | +.heatmap-legend{display:flex;gap:3px;align-items:center} |
| 111 | + |
| 112 | +/* footer */ |
| 113 | +.profile-footer{margin-top:24px;padding-top:16px;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;font-size:10px;color:var(--text-dim)} |
| 114 | +.footer-brand{color:var(--green);text-decoration:none;font-weight:700;letter-spacing:.5px} |
| 115 | + |
| 116 | +@media(max-width:640px){ |
| 117 | + .profile-header{flex-direction:column} |
| 118 | + .stat-grid{grid-template-columns:repeat(2,1fr)} |
| 119 | + .repo-grid{grid-template-columns:1fr} |
| 120 | + .search-box{width:calc(100vw - 40px);padding:28px 20px} |
| 121 | +} |
| 122 | +</style> |
| 123 | +</head> |
| 124 | +<body> |
| 125 | +<div class="page"> |
| 126 | + |
| 127 | + <!-- Loading --> |
| 128 | + <div id="loading" class="active"> |
| 129 | + <div class="loader-text">// fetching profile...</div> |
| 130 | + <div class="loader-bar"></div> |
| 131 | + </div> |
| 132 | + |
| 133 | + <!-- Not found --> |
| 134 | + <div id="not-found"> |
| 135 | + <div class="nf-code">404</div> |
| 136 | + <div class="nf-msg">profile not found</div> |
| 137 | + <a href="profile.html" style="color:var(--blue);font-size:12px;margin-top:8px">← search profiles</a> |
| 138 | + </div> |
| 139 | + |
| 140 | + <!-- Search (no slug) --> |
| 141 | + <div id="search-screen"> |
| 142 | + <div class="search-box"> |
| 143 | + <div class="s-corner tl"></div><div class="s-corner tr"></div> |
| 144 | + <div class="s-corner bl"></div><div class="s-corner br"></div> |
| 145 | + <div class="s-title">dev_profile</div> |
| 146 | + <div class="s-sub">// public developer profiles</div> |
| 147 | + <div class="s-row"> |
| 148 | + <input class="s-input" id="slug-input" placeholder="paste profile slug or url..." autocomplete="off" spellcheck="false" /> |
| 149 | + <button class="s-btn" onclick="goToSlug()">view →</button> |
| 150 | + </div> |
| 151 | + </div> |
| 152 | + </div> |
| 153 | + |
| 154 | + <!-- Profile content --> |
| 155 | + <div id="profile-content"> |
| 156 | + |
| 157 | + <!-- Header --> |
| 158 | + <div class="profile-header"> |
| 159 | + <div class="avatar"><img id="p-avatar" src="" alt="" /></div> |
| 160 | + <div class="profile-info"> |
| 161 | + <div class="profile-name" id="p-name">—</div> |
| 162 | + <div class="profile-login"> |
| 163 | + <span class="online-dot"></span> |
| 164 | + <span id="p-login">—</span> |
| 165 | + </div> |
| 166 | + <div class="profile-bio" id="p-bio"></div> |
| 167 | + <div class="profile-meta" id="p-meta"></div> |
| 168 | + </div> |
| 169 | + <div class="profile-actions"> |
| 170 | + <a id="p-gh-link" href="#" target="_blank" class="btn-gh">github ↗</a> |
| 171 | + <button class="btn-copy" onclick="copyURL()">copy url</button> |
| 172 | + </div> |
| 173 | + </div> |
| 174 | + |
| 175 | + <!-- Stats --> |
| 176 | + <div class="stat-grid"> |
| 177 | + <div class="stat-card"><span class="stat-val" id="p-repos">—</span><span class="stat-label">repos</span></div> |
| 178 | + <div class="stat-card"><span class="stat-val" id="p-stars">—</span><span class="stat-label">stars</span></div> |
| 179 | + <div class="stat-card"><span class="stat-val" id="p-followers">—</span><span class="stat-label">followers</span></div> |
| 180 | + <div class="stat-card"><span class="stat-val" id="p-forks">—</span><span class="stat-label">forks</span></div> |
| 181 | + </div> |
| 182 | + |
| 183 | + <!-- Heatmap --> |
| 184 | + <div class="section"> |
| 185 | + <div class="section-title"><span class="section-icon"></span>contribution activity (last 6 months)</div> |
| 186 | + <div class="heatmap-wrap"> |
| 187 | + <div class="heatmap-grid" id="p-heatmap"></div> |
| 188 | + </div> |
| 189 | + <div class="heatmap-footer"> |
| 190 | + <span>less</span> |
| 191 | + <div class="heatmap-legend"> |
| 192 | + <div class="heatmap-cell" data-count="0"></div> |
| 193 | + <div class="heatmap-cell" data-level="1"></div> |
| 194 | + <div class="heatmap-cell" data-level="2"></div> |
| 195 | + <div class="heatmap-cell" data-level="3"></div> |
| 196 | + <div class="heatmap-cell" data-level="4"></div> |
| 197 | + </div> |
| 198 | + <span>more</span> |
| 199 | + <span style="margin-left:auto;color:var(--green)" id="p-commits">—</span> |
| 200 | + </div> |
| 201 | + </div> |
| 202 | + |
| 203 | + <!-- Languages --> |
| 204 | + <div class="section"> |
| 205 | + <div class="section-title"><span class="section-icon"></span>language breakdown</div> |
| 206 | + <div id="p-langs"></div> |
| 207 | + </div> |
| 208 | + |
| 209 | + <!-- Top repos --> |
| 210 | + <div class="section"> |
| 211 | + <div class="section-title"><span class="section-icon"></span>top repositories</div> |
| 212 | + <div class="repo-grid" id="p-repos-list"></div> |
| 213 | + </div> |
| 214 | + |
| 215 | + <!-- Footer --> |
| 216 | + <div class="profile-footer"> |
| 217 | + <span>generated by <a class="footer-brand" href="https://dev0root6.github.io/dev-dashboard/">dev_dashboard</a></span> |
| 218 | + <span>data from github api · updates on login</span> |
| 219 | + </div> |
| 220 | + |
| 221 | + </div> |
| 222 | +</div> |
| 223 | + |
| 224 | +<script> |
| 225 | +const API_BASE = 'https://dev-dashboard-api.devsekarindhu18.workers.dev'; |
| 226 | + |
| 227 | +const LANG_COLORS = { |
| 228 | + Python:'#3572A5',JavaScript:'#f1e05a',TypeScript:'#2b7489', |
| 229 | + Go:'#00ADD8',C:'#555555','C++':'#f34b7d',Rust:'#dea584', |
| 230 | + Shell:'#89e051',HTML:'#e34c26',CSS:'#563d7c',Java:'#b07219', |
| 231 | + Ruby:'#701516',Swift:'#ffac45',Kotlin:'#F18E33',default:'#00ff88' |
| 232 | +}; |
| 233 | +function lc(l){return LANG_COLORS[l]||LANG_COLORS.default} |
| 234 | +function fmtNum(n){return n>=1000?(n/1000).toFixed(1)+'k':String(n)} |
| 235 | + |
| 236 | +function show(id){ |
| 237 | + ['loading','not-found','search-screen','profile-content'].forEach(s=>{ |
| 238 | + const el=document.getElementById(s); |
| 239 | + el.classList.remove('active'); |
| 240 | + if(s==='profile-content') el.style.display='none'; |
| 241 | + }); |
| 242 | + const target=document.getElementById(id); |
| 243 | + target.classList.add('active'); |
| 244 | + if(id==='profile-content') target.style.display='block'; |
| 245 | +} |
| 246 | + |
| 247 | +async function loadProfile(slug){ |
| 248 | + show('loading'); |
| 249 | + try{ |
| 250 | + const res=await fetch(`${API_BASE}/public/${slug}`); |
| 251 | + if(!res.ok){ show('not-found'); return; } |
| 252 | + const d=await res.json(); |
| 253 | + if(d.error){ show('not-found'); return; } |
| 254 | + renderProfile(d); |
| 255 | + show('profile-content'); |
| 256 | + |
| 257 | + // update page title and meta |
| 258 | + document.title=`${d.name||d.login} — dev_profile`; |
| 259 | + document.getElementById('og-title').content=`${d.name||d.login} on dev_dashboard`; |
| 260 | + document.getElementById('og-desc').content=d.bio||`@${d.login} — ${d.public_repos} repos · ${fmtNum(d.total_stars)} stars`; |
| 261 | + }catch(e){ |
| 262 | + show('not-found'); |
| 263 | + } |
| 264 | +} |
| 265 | + |
| 266 | +function renderProfile(d){ |
| 267 | + document.getElementById('p-avatar').src=d.avatar_url||''; |
| 268 | + document.getElementById('p-name').textContent=d.name||d.login; |
| 269 | + document.getElementById('p-login').textContent=`@${d.login}`; |
| 270 | + document.getElementById('p-gh-link').href=`https://github.com/${d.login}`; |
| 271 | + |
| 272 | + const bio=document.getElementById('p-bio'); |
| 273 | + bio.textContent=d.bio||''; |
| 274 | + bio.style.display=d.bio?'block':'none'; |
| 275 | + |
| 276 | + // meta items |
| 277 | + const metas=[]; |
| 278 | + if(d.location) metas.push(`📍 ${d.location}`); |
| 279 | + if(d.blog) metas.push(`<a href="${d.blog.startsWith('http')?d.blog:'https://'+d.blog}" target="_blank" rel="noopener">${d.blog}</a>`); |
| 280 | + if(d.twitter_username) metas.push(`@${d.twitter_username}`); |
| 281 | + if(d.created_at) metas.push(`joined ${new Date(d.created_at).getFullYear()}`); |
| 282 | + document.getElementById('p-meta').innerHTML=metas.map(m=>`<span class="meta-item">${m}</span>`).join(''); |
| 283 | + |
| 284 | + // stats |
| 285 | + document.getElementById('p-repos').textContent=d.public_repos||0; |
| 286 | + document.getElementById('p-stars').textContent=fmtNum(d.total_stars||0); |
| 287 | + document.getElementById('p-followers').textContent=fmtNum(d.followers||0); |
| 288 | + document.getElementById('p-forks').textContent=fmtNum(d.total_forks||0); |
| 289 | + |
| 290 | + renderHeatmap(d.heatmap||{}); |
| 291 | + renderLangs(d.languages||{}); |
| 292 | + renderRepos(d.top_repos||[]); |
| 293 | +} |
| 294 | + |
| 295 | +function renderHeatmap(heatmap){ |
| 296 | + const today=new Date(), weeks=26; |
| 297 | + const startDate=new Date(today); |
| 298 | + startDate.setDate(startDate.getDate()-weeks*7+1); |
| 299 | + const container=document.getElementById('p-heatmap'); |
| 300 | + container.innerHTML=''; |
| 301 | + let total=0; |
| 302 | + |
| 303 | + for(let w=0;w<weeks;w++){ |
| 304 | + const weekDiv=document.createElement('div'); |
| 305 | + weekDiv.className='heatmap-week'; |
| 306 | + for(let d=0;d<7;d++){ |
| 307 | + const date=new Date(startDate); |
| 308 | + date.setDate(startDate.getDate()+w*7+d); |
| 309 | + const cell=document.createElement('div'); |
| 310 | + cell.className='heatmap-cell'; |
| 311 | + if(date>today){cell.style.opacity='0';weekDiv.appendChild(cell);continue} |
| 312 | + const key=date.toISOString().split('T')[0]; |
| 313 | + const count=heatmap[key]||0; |
| 314 | + total+=count; |
| 315 | + if(count===0)cell.setAttribute('data-count','0'); |
| 316 | + else if(count<=2)cell.setAttribute('data-level','1'); |
| 317 | + else if(count<=5)cell.setAttribute('data-level','2'); |
| 318 | + else if(count<=10)cell.setAttribute('data-level','3'); |
| 319 | + else cell.setAttribute('data-level','4'); |
| 320 | + cell.title=`${key}: ${count} commit${count!==1?'s':''}`; |
| 321 | + weekDiv.appendChild(cell); |
| 322 | + } |
| 323 | + container.appendChild(weekDiv); |
| 324 | + } |
| 325 | + document.getElementById('p-commits').textContent=`${total} commits`; |
| 326 | +} |
| 327 | + |
| 328 | +function renderLangs(langMap){ |
| 329 | + const sorted=Object.entries(langMap).sort((a,b)=>b[1]-a[1]).slice(0,8); |
| 330 | + const total=sorted.reduce((a,b)=>a+b[1],0); |
| 331 | + document.getElementById('p-langs').innerHTML=sorted.map(([l,c])=>{ |
| 332 | + const pct=Math.round(c/total*100); |
| 333 | + return`<div class="lang-bar-item"> |
| 334 | + <span class="lang-name">${l}</span> |
| 335 | + <div class="lang-bar-bg"><div class="lang-bar-fill" style="width:${pct}%;background:${lc(l)}"></div></div> |
| 336 | + <span class="lang-pct">${pct}%</span> |
| 337 | + </div>`; |
| 338 | + }).join(''); |
| 339 | +} |
| 340 | + |
| 341 | +function renderRepos(repos){ |
| 342 | + document.getElementById('p-repos-list').innerHTML=repos.map(r=>` |
| 343 | + <a class="repo-card" href="${r.html_url}" target="_blank" rel="noopener"> |
| 344 | + <div class="repo-name">${r.name} ↗</div> |
| 345 | + <div class="repo-desc">${r.description||'no description'}</div> |
| 346 | + <div class="repo-meta"> |
| 347 | + ${r.language?`<span><span class="lang-dot" style="background:${lc(r.language)}"></span>${r.language}</span>`:''} |
| 348 | + <span class="stars">★ ${fmtNum(r.stargazers_count)}</span> |
| 349 | + <span>⑂ ${fmtNum(r.forks_count)}</span> |
| 350 | + </div> |
| 351 | + </a>`).join(''); |
| 352 | +} |
| 353 | + |
| 354 | +function copyURL(){ |
| 355 | + navigator.clipboard.writeText(window.location.href).then(()=>{ |
| 356 | + const btn=document.querySelector('.btn-copy'); |
| 357 | + btn.textContent='copied!'; |
| 358 | + btn.style.borderColor='var(--green)'; |
| 359 | + btn.style.color='var(--green)'; |
| 360 | + setTimeout(()=>{btn.textContent='copy url';btn.style.borderColor='';btn.style.color='';},2000); |
| 361 | + }); |
| 362 | +} |
| 363 | + |
| 364 | +function goToSlug(){ |
| 365 | + const val=document.getElementById('slug-input').value.trim(); |
| 366 | + if(!val)return; |
| 367 | + // support pasting full URL or just slug |
| 368 | + const match=val.match(/[?&]u=([a-z0-9-]+)/)||val.match(/^([a-z0-9-]+)$/); |
| 369 | + if(match) window.location.href=`profile.html?u=${match[1]}`; |
| 370 | +} |
| 371 | + |
| 372 | +// Init |
| 373 | +window.addEventListener('DOMContentLoaded',()=>{ |
| 374 | + const params=new URLSearchParams(window.location.search); |
| 375 | + const slug=params.get('u'); |
| 376 | + if(slug){ |
| 377 | + loadProfile(slug); |
| 378 | + } else { |
| 379 | + show('search-screen'); |
| 380 | + } |
| 381 | + document.getElementById('slug-input')?.addEventListener('keydown',e=>{if(e.key==='Enter')goToSlug()}); |
| 382 | +}); |
| 383 | +</script> |
| 384 | +</body> |
| 385 | +</html> |
0 commit comments