Skip to content

Commit d55c0cc

Browse files
author
danil-nizamov
committed
added optional stats
1 parent 52be2b9 commit d55c0cc

File tree

6 files changed

+398
-22
lines changed

6 files changed

+398
-22
lines changed

client/config.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
{
2-
"keyboard": true
2+
"keyboard": true,
3+
"availableKeys": [],
4+
"showStats": true
35
}

client/index.html

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,47 @@ <h2>Completed</h2>
5555
<p>Great job! You've finished typing the text.</p>
5656
<button id="btn-start-over" class="button button-primary">Start Over</button>
5757
</div>
58+
<div id="stats-dashboard" class="stats-dashboard">
59+
<div class="stats-dashboard-header">
60+
<h2>Typing Statistics</h2>
61+
<p class="stats-subtitle">Your performance summary</p>
62+
</div>
63+
<div class="stats-grid">
64+
<div class="stat-card">
65+
<div class="stat-value-container">
66+
<span class="stat-value" id="stat-speed">0</span>
67+
</div>
68+
<div class="stat-label">WPM</div>
69+
</div>
70+
<div class="stat-card">
71+
<div class="stat-value-container">
72+
<span class="stat-value" id="stat-accuracy">0%</span>
73+
</div>
74+
<div class="stat-label">Accuracy</div>
75+
</div>
76+
<div class="stat-card">
77+
<div class="stat-value-container">
78+
<span class="stat-value" id="stat-time">0s</span>
79+
</div>
80+
<div class="stat-label">Total time</div>
81+
</div>
82+
<div class="stat-card">
83+
<div class="stat-value-container">
84+
<span class="stat-value" id="stat-errors">0</span>
85+
</div>
86+
<div class="stat-label">Total errors</div>
87+
</div>
88+
<div class="stat-card">
89+
<div class="stat-value-container">
90+
<span class="stat-value" id="stat-errors-left">0</span>
91+
</div>
92+
<div class="stat-label">Errors left</div>
93+
</div>
94+
</div>
95+
<div class="stats-dashboard-footer">
96+
<button id="btn-stats-start-over" class="button button-primary">Start Over</button>
97+
</div>
98+
</div>
5899
<div class="restart-button-container">
59100
<button id="btn-restart" class="button button-text" title="Start Over">
60101
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">

client/stats.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Typing Statistics
22
==================
33

4-
Total Errors Made: 0
5-
Errors Left (Unfixed): 0
6-
Total Time: 2.76 seconds
7-
Accuracy: 100.00%
8-
Speed: 87.05 words per minute
4+
Total Errors Made: 8
5+
Errors Left (Unfixed): 5
6+
Total Time: 17.31 seconds
7+
Accuracy: 86.89%
8+
Speed: 34.66 words per minute
99

10-
Generated: 26/11/2025, 04:24:59
10+
Generated: 26/11/2025, 06:10:40

client/text-to-input.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
1+
testing text.
2+
3+
with newlines!
4+
5+
And special symbols: \ [ `.

client/typing-simulator.css

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,98 @@
160160
margin: 0;
161161
}
162162

163+
/* Stats Dashboard Styles */
164+
.bespoke .stats-dashboard {
165+
display: none;
166+
position: fixed;
167+
top: 50%;
168+
left: 50%;
169+
transform: translate(-50%, -50%);
170+
flex-direction: column;
171+
align-items: center;
172+
justify-content: center;
173+
gap: var(--UI-Spacing-spacing-xl);
174+
padding: var(--UI-Spacing-spacing-xxxl);
175+
background: var(--Colors-Box-Background);
176+
border-radius: var(--UI-Radius-radius-m);
177+
border: 1px solid var(--Colors-Stroke-Default);
178+
text-align: center;
179+
z-index: 1000;
180+
min-width: 600px;
181+
max-width: 800px;
182+
box-shadow: 0 3px 2px 0 var(--Colors-Shadow-Card);
183+
}
184+
185+
.bespoke .stats-dashboard-header {
186+
width: 100%;
187+
margin-bottom: var(--UI-Spacing-spacing-lg);
188+
}
189+
190+
.bespoke .stats-dashboard-header h2 {
191+
font-size: var(--Fonts-Headlines-xl);
192+
margin: 0 0 var(--UI-Spacing-spacing-xs) 0;
193+
color: var(--Colors-Text-Body-Strongest);
194+
font-family: var(--heading-family);
195+
font-weight: 500;
196+
}
197+
198+
.bespoke .stats-subtitle {
199+
font-size: var(--Fonts-Body-Default-md);
200+
color: var(--Colors-Text-Body-Medium);
201+
margin: 0;
202+
}
203+
204+
.bespoke .stats-grid {
205+
display: grid;
206+
grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
207+
gap: var(--UI-Spacing-spacing-xl);
208+
width: 100%;
209+
margin: var(--UI-Spacing-spacing-lg) 0;
210+
}
211+
212+
.bespoke .stat-card {
213+
display: flex;
214+
flex-direction: column;
215+
align-items: center;
216+
justify-content: center;
217+
padding: var(--UI-Spacing-spacing-xl);
218+
background: var(--Colors-Box-Background-Secondary);
219+
border: 1px solid var(--Colors-Stroke-Default);
220+
border-radius: var(--UI-Radius-radius-m);
221+
transition: transform 0.2s ease, box-shadow 0.2s ease;
222+
}
223+
224+
.bespoke .stat-card:hover {
225+
transform: translateY(-2px);
226+
box-shadow: 0 4px 8px 0 var(--Colors-Shadow-Card);
227+
}
228+
229+
.bespoke .stat-value-container {
230+
display: flex;
231+
align-items: center;
232+
justify-content: center;
233+
margin-bottom: var(--UI-Spacing-spacing-xs);
234+
}
235+
236+
.bespoke .stat-value {
237+
font-size: var(--Fonts-Headlines-md);
238+
font-weight: 600;
239+
color: var(--Colors-Primary-Default);
240+
font-family: var(--heading-family);
241+
}
242+
243+
.bespoke .stat-label {
244+
font-size: var(--Fonts-Body-Default-sm);
245+
color: var(--Colors-Text-Body-Medium);
246+
text-transform: uppercase;
247+
letter-spacing: 0.5px;
248+
}
249+
250+
.bespoke .stats-dashboard-footer {
251+
width: 100%;
252+
margin-top: var(--UI-Spacing-spacing-lg);
253+
}
254+
163255
/* Mini Keyboard Styles */
164256
.bespoke .keyboard-container {
165257
display: none;
@@ -240,3 +332,11 @@
240332
border-color: var(--Colors-Alert-Error-Default);
241333
transform: scale(0.95);
242334
}
335+
336+
.bespoke .keyboard-key.unavailable {
337+
background: var(--Colors-Box-Background);
338+
border-color: var(--Colors-Stroke-Light);
339+
color: var(--Colors-Text-Body-Light);
340+
opacity: 0.5;
341+
cursor: not-allowed;
342+
}

0 commit comments

Comments
 (0)