Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.

Commit c8c8cf2

Browse files
author
Claude Usage Tracker
committed
Add 100M token goal tracker to GitHub Pages
1 parent 10f11e8 commit c8c8cf2

2 files changed

Lines changed: 223 additions & 677 deletions

File tree

create_index.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/usr/bin/env python3
2+
"""Create index.html for GitHub Pages"""
3+
4+
html = """<!DOCTYPE html>
5+
<html lang="ko">
6+
<head>
7+
<meta charset="UTF-8">
8+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
9+
<title>🎯 Claude 100M Token Goal Tracker</title>
10+
<style>
11+
* { margin: 0; padding: 0; box-sizing: border-box; }
12+
body {
13+
font-family: 'Segoe UI', sans-serif;
14+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
15+
min-height: 100vh;
16+
display: flex;
17+
justify-content: center;
18+
align-items: center;
19+
padding: 20px;
20+
}
21+
.container {
22+
background: white;
23+
border-radius: 20px;
24+
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
25+
max-width: 800px;
26+
width: 100%;
27+
padding: 40px;
28+
}
29+
.header { text-align: center; margin-bottom: 40px; }
30+
.header h1 { font-size: 2.5em; color: #333; margin-bottom: 10px; }
31+
.deadline { color: #666; font-size: 1.2em; }
32+
.stats-grid {
33+
display: grid;
34+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
35+
gap: 20px;
36+
margin-bottom: 40px;
37+
}
38+
.stat-card {
39+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
40+
color: white;
41+
padding: 20px;
42+
border-radius: 15px;
43+
text-align: center;
44+
}
45+
.stat-card .label { font-size: 0.9em; opacity: 0.9; margin-bottom: 5px; }
46+
.stat-card .value { font-size: 2em; font-weight: bold; }
47+
.progress-section { margin: 40px 0; }
48+
.progress-header {
49+
display: flex;
50+
justify-content: space-between;
51+
margin-bottom: 10px;
52+
}
53+
.progress-label { font-size: 1.2em; color: #333; font-weight: bold; }
54+
.progress-percentage { font-size: 1.5em; font-weight: bold; color: #667eea; }
55+
.progress-bar-container {
56+
background: #e0e0e0;
57+
border-radius: 50px;
58+
height: 40px;
59+
overflow: hidden;
60+
margin-bottom: 20px;
61+
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
62+
}
63+
.progress-bar {
64+
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
65+
height: 100%;
66+
border-radius: 50px;
67+
transition: width 1s ease-out;
68+
}
69+
.progress-details {
70+
display: grid;
71+
grid-template-columns: repeat(3, 1fr);
72+
gap: 15px;
73+
text-align: center;
74+
}
75+
.progress-detail {
76+
padding: 15px;
77+
background: #f5f5f5;
78+
border-radius: 10px;
79+
}
80+
.progress-detail .label { color: #666; font-size: 0.9em; margin-bottom: 5px; }
81+
.progress-detail .value { color: #333; font-size: 1.3em; font-weight: bold; }
82+
.projection {
83+
margin-top: 30px;
84+
padding: 20px;
85+
background: #fff3cd;
86+
border-radius: 10px;
87+
border-left: 4px solid #ffc107;
88+
}
89+
.projection.success { background: #d4edda; border-left-color: #28a745; }
90+
.projection.warning { background: #f8d7da; border-left-color: #dc3545; }
91+
.projection-title { font-size: 1.2em; font-weight: bold; margin-bottom: 10px; color: #333; }
92+
.loading { text-align: center; padding: 40px; color: #666; }
93+
</style>
94+
</head>
95+
<body>
96+
<div class="container">
97+
<div class="header">
98+
<h1>🎯 Claude 100M Token Goal</h1>
99+
<p class="deadline">Deadline: December 31, 2025</p>
100+
</div>
101+
<div id="loading" class="loading"><p>Loading data...</p></div>
102+
<div id="content" style="display: none;">
103+
<div class="stats-grid">
104+
<div class="stat-card"><div class="label">Total Devices</div><div class="value" id="totalDevices">-</div></div>
105+
<div class="stat-card"><div class="label">Total Sessions</div><div class="value" id="totalSessions">-</div></div>
106+
<div class="stat-card"><div class="label">Total Cost</div><div class="value" id="totalCost">-</div></div>
107+
</div>
108+
<div class="progress-section">
109+
<div class="progress-header">
110+
<span class="progress-label">🎯 Goal Progress</span>
111+
<span class="progress-percentage" id="percentage">0%</span>
112+
</div>
113+
<div class="progress-bar-container">
114+
<div class="progress-bar" id="progressBar" style="width: 0%"></div>
115+
</div>
116+
<div class="progress-details">
117+
<div class="progress-detail"><div class="label">Target</div><div class="value">100.00M</div></div>
118+
<div class="progress-detail"><div class="label">Current</div><div class="value" id="current">0M</div></div>
119+
<div class="progress-detail"><div class="label">Remaining</div><div class="value" id="remaining">0M</div></div>
120+
</div>
121+
</div>
122+
<div id="projection" class="projection" style="display: none;">
123+
<div class="projection-title">🔮 Projection</div>
124+
<div id="projectionContent"></div>
125+
</div>
126+
</div>
127+
</div>
128+
<script>
129+
const GOAL=100000000;function fmt(t){return(t/1000000).toFixed(2)+"M"}async function load(){try{const devs=['yangpyungpc','bohees-macbook-air-local'];const data=(await Promise.all(devs.map(async d=>{const r=await fetch(`data/${d}.json`);return r.ok?await r.json():null}))).filter(d=>d);const u={i:0,o:0,c:0,s:0};let cost=0;data.forEach(d=>{u.i+=d.usage.input_tokens||0;u.o+=d.usage.output_tokens||0;u.c+=d.usage.cache_creation_tokens||0;u.s+=d.usage.total_sessions||0;cost+=d.estimated_cost||0});const tot=u.i+u.o+u.c,rem=GOAL-tot,pct=tot/GOAL*100;document.getElementById('totalDevices').textContent=data.length;document.getElementById('totalSessions').textContent=u.s.toLocaleString();document.getElementById('totalCost').textContent='$'+cost.toFixed(2);document.getElementById('percentage').textContent=pct.toFixed(1)+'%';document.getElementById('current').textContent=fmt(tot);document.getElementById('remaining').textContent=fmt(rem);setTimeout(()=>document.getElementById('progressBar').style.width=Math.min(pct,100)+'%',100);const now=new Date(),dl=new Date('2025-12-31T23:59:59Z'),ps=new Date('2025-10-01T00:00:00Z');const dr=Math.ceil((dl-now)/86400000);if(dr>0){const de=Math.max(1,Math.ceil((now-ps)/86400000)),avg=tot/de;const td=Math.ceil((dl-ps)/86400000),proj=avg*td,dt=rem/dr;const p=document.getElementById('projection');p.style.display='block';let h=`<p><strong>Days remaining:</strong> ${dr}</p>`;h+=`<p><strong>Daily target:</strong> ${fmt(dt)}</p>`;h+=`<p><strong>Current pace:</strong> ${fmt(avg)}/day</p>`;h+=`<p><strong>Projected total:</strong> ${fmt(proj)}</p>`;if(proj>=GOAL){p.className='projection success';h+=`<p style="margin-top:10px;font-weight:bold;">✅ ON TRACK! (+${fmt(proj-GOAL)})</p>`}else{p.className='projection warning';h+=`<p style="margin-top:10px;font-weight:bold;">⚠️ BEHIND PACE (-${fmt(GOAL-proj)})<br>Need +${fmt(dt-avg)}/day</p>`}document.getElementById('projectionContent').innerHTML=h}document.getElementById('loading').style.display='none';document.getElementById('content').style.display='block'}catch(e){document.getElementById('loading').innerHTML='<p>❌ Error loading data</p>'}}load();setInterval(load,300000);
130+
</script>
131+
</body>
132+
</html>"""
133+
134+
with open('C:/Users/user/claude-usage-tracker/index.html', 'w', encoding='utf-8') as f:
135+
f.write(html)
136+
137+
print('✅ Created index.html')

0 commit comments

Comments
 (0)