studyup 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/2048-package/README.md +29 -0
- package/2048-package/assets/Screenshots-2048-Game.jpg +0 -0
- package/2048-package/css/style.css +69 -0
- package/2048-package/index.html +23 -0
- package/2048-package/src/script.js +270 -0
- package/classicube-package/README.md +5 -0
- package/classicube-package/css/style.css +7 -0
- package/classicube-package/index.html +72 -0
- package/classicube-package/js/ClassiCube.js +63288 -0
- package/classicube-package/js/jquery.js +2 -0
- package/classicube-package/static/default.zip +0 -0
- package/index.html +298 -43
- package/package.json +2 -2
package/index.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>StudyUp</title>
|
|
6
|
+
<title>StudyUp - Student Portal</title>
|
|
7
7
|
<!-- Material Design 1 / Roboto Typography & Icons -->
|
|
8
8
|
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700&display=swap" rel="stylesheet">
|
|
9
9
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
|
@@ -13,10 +13,12 @@
|
|
|
13
13
|
:root {
|
|
14
14
|
--primary-color: #3f51b5; /* Indigo */
|
|
15
15
|
--primary-dark: #303f9f;
|
|
16
|
+
--accent-color: #ff4081;
|
|
16
17
|
--background-color: #eeeeee;
|
|
17
18
|
--card-background: #ffffff;
|
|
18
19
|
--text-primary: rgba(0, 0, 0, 0.87);
|
|
19
20
|
--text-secondary: rgba(0, 0, 0, 0.54);
|
|
21
|
+
--error-color: #d32f2f;
|
|
20
22
|
--shadow-elevation-2: 0 3px 1px -2px rgba(0,0,0,0.2), 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12);
|
|
21
23
|
--shadow-elevation-4: 0 4px 5px -2px rgba(0,0,0,0.2), 0 7px 10px 1px rgba(0,0,0,0.14), 0 2px 16px 1px rgba(0,0,0,0.12);
|
|
22
24
|
}
|
|
@@ -30,6 +32,7 @@
|
|
|
30
32
|
display: flex;
|
|
31
33
|
flex-direction: column;
|
|
32
34
|
min-height: 100vh;
|
|
35
|
+
justify-content: space-between;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
/* Material Toolbar (Header) */
|
|
@@ -50,8 +53,153 @@
|
|
|
50
53
|
letter-spacing: 0.5px;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
/*
|
|
56
|
+
/* View Switching (Login vs Portal Dashboard) */
|
|
57
|
+
.view {
|
|
58
|
+
display: none;
|
|
59
|
+
flex: 1;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
}
|
|
62
|
+
.view.active {
|
|
63
|
+
display: flex;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Main Container & Login Card */
|
|
54
67
|
.container {
|
|
68
|
+
max-width: 420px;
|
|
69
|
+
width: 100%;
|
|
70
|
+
margin: auto;
|
|
71
|
+
padding: 16px;
|
|
72
|
+
box-sizing: border-box;
|
|
73
|
+
flex: 1;
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.card {
|
|
80
|
+
background-color: var(--card-background);
|
|
81
|
+
border-radius: 2px;
|
|
82
|
+
box-shadow: var(--shadow-elevation-4);
|
|
83
|
+
padding: 32px 24px;
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-direction: column;
|
|
86
|
+
align-items: center;
|
|
87
|
+
text-align: center;
|
|
88
|
+
width: 100%;
|
|
89
|
+
box-sizing: border-box;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.card-icon-wrapper {
|
|
93
|
+
background-color: rgba(63, 81, 181, 0.1);
|
|
94
|
+
color: var(--primary-color);
|
|
95
|
+
width: 64px;
|
|
96
|
+
height: 64px;
|
|
97
|
+
border-radius: 50%;
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
justify-content: center;
|
|
101
|
+
margin-bottom: 20px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.card-icon-wrapper i {
|
|
105
|
+
font-size: 32px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.card-title {
|
|
109
|
+
font-size: 24px;
|
|
110
|
+
font-weight: 500;
|
|
111
|
+
margin: 0 0 8px 0;
|
|
112
|
+
color: var(--text-primary);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.card-subtitle {
|
|
116
|
+
font-size: 14px;
|
|
117
|
+
color: var(--text-secondary);
|
|
118
|
+
margin: 0 0 24px 0;
|
|
119
|
+
line-height: 1.4;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Material Floating Label Input Field */
|
|
123
|
+
.input-container {
|
|
124
|
+
position: relative;
|
|
125
|
+
margin-bottom: 24px;
|
|
126
|
+
width: 100%;
|
|
127
|
+
text-align: left;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.input-container input {
|
|
131
|
+
width: 100%;
|
|
132
|
+
padding: 12px;
|
|
133
|
+
font-size: 16px;
|
|
134
|
+
font-family: 'Roboto', sans-serif;
|
|
135
|
+
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
136
|
+
border-radius: 2px;
|
|
137
|
+
outline: none;
|
|
138
|
+
box-sizing: border-box;
|
|
139
|
+
background: transparent;
|
|
140
|
+
transition: border-color 0.2s;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.input-container input:focus {
|
|
144
|
+
border-color: var(--primary-color);
|
|
145
|
+
border-width: 2px;
|
|
146
|
+
padding: 11px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.input-container label {
|
|
150
|
+
position: absolute;
|
|
151
|
+
left: 12px;
|
|
152
|
+
top: 14px;
|
|
153
|
+
color: var(--text-secondary);
|
|
154
|
+
font-size: 16px;
|
|
155
|
+
pointer-events: none;
|
|
156
|
+
transition: 0.2s ease all;
|
|
157
|
+
background: white;
|
|
158
|
+
padding: 0 4px;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.input-container input:focus ~ label,
|
|
162
|
+
.input-container input:not(:placeholder-shown) ~ label {
|
|
163
|
+
top: -10px;
|
|
164
|
+
font-size: 12px;
|
|
165
|
+
color: var(--primary-color);
|
|
166
|
+
font-weight: 500;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* Error Message */
|
|
170
|
+
#error-msg {
|
|
171
|
+
color: var(--error-color);
|
|
172
|
+
font-size: 13px;
|
|
173
|
+
margin-bottom: 16px;
|
|
174
|
+
display: none;
|
|
175
|
+
font-weight: 500;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Material Raised Button */
|
|
179
|
+
.btn-raised {
|
|
180
|
+
background-color: var(--primary-color);
|
|
181
|
+
color: white;
|
|
182
|
+
border: none;
|
|
183
|
+
font-family: 'Roboto', sans-serif;
|
|
184
|
+
font-weight: 500;
|
|
185
|
+
font-size: 14px;
|
|
186
|
+
text-transform: uppercase;
|
|
187
|
+
padding: 12px 24px;
|
|
188
|
+
border-radius: 2px;
|
|
189
|
+
cursor: pointer;
|
|
190
|
+
width: 100%;
|
|
191
|
+
box-shadow: var(--shadow-elevation-2);
|
|
192
|
+
transition: background-color 0.2s, box-shadow 0.2s;
|
|
193
|
+
letter-spacing: 0.5px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.btn-raised:hover {
|
|
197
|
+
background-color: var(--primary-dark);
|
|
198
|
+
box-shadow: var(--shadow-elevation-4);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Portal Dashboard Grid */
|
|
202
|
+
.portal-container {
|
|
55
203
|
max-width: 900px;
|
|
56
204
|
width: 100%;
|
|
57
205
|
margin: 40px auto;
|
|
@@ -63,8 +211,7 @@
|
|
|
63
211
|
flex: 1;
|
|
64
212
|
}
|
|
65
213
|
|
|
66
|
-
|
|
67
|
-
.card {
|
|
214
|
+
.portal-card {
|
|
68
215
|
background-color: var(--card-background);
|
|
69
216
|
border-radius: 2px;
|
|
70
217
|
box-shadow: var(--shadow-elevation-2);
|
|
@@ -74,7 +221,7 @@
|
|
|
74
221
|
overflow: hidden;
|
|
75
222
|
}
|
|
76
223
|
|
|
77
|
-
.card:hover {
|
|
224
|
+
.portal-card:hover {
|
|
78
225
|
box-shadow: var(--shadow-elevation-4);
|
|
79
226
|
}
|
|
80
227
|
|
|
@@ -91,7 +238,7 @@
|
|
|
91
238
|
flex: 1;
|
|
92
239
|
}
|
|
93
240
|
|
|
94
|
-
.card-title {
|
|
241
|
+
.portal-card-title {
|
|
95
242
|
font-size: 20px;
|
|
96
243
|
font-weight: 500;
|
|
97
244
|
margin: 0 0 8px 0;
|
|
@@ -105,7 +252,6 @@
|
|
|
105
252
|
margin: 0;
|
|
106
253
|
}
|
|
107
254
|
|
|
108
|
-
/* Material Action Area & Flat Button */
|
|
109
255
|
.card-actions {
|
|
110
256
|
padding: 8px 16px 16px 16px;
|
|
111
257
|
display: flex;
|
|
@@ -174,7 +320,13 @@
|
|
|
174
320
|
font-weight: 500;
|
|
175
321
|
}
|
|
176
322
|
|
|
177
|
-
.
|
|
323
|
+
.modal-header-actions {
|
|
324
|
+
display: flex;
|
|
325
|
+
align-items: center;
|
|
326
|
+
gap: 8px;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.modal-btn {
|
|
178
330
|
background: transparent;
|
|
179
331
|
border: none;
|
|
180
332
|
color: white;
|
|
@@ -183,12 +335,12 @@
|
|
|
183
335
|
display: flex;
|
|
184
336
|
align-items: center;
|
|
185
337
|
justify-content: center;
|
|
186
|
-
padding:
|
|
338
|
+
padding: 6px;
|
|
187
339
|
border-radius: 50%;
|
|
188
340
|
transition: background-color 0.2s;
|
|
189
341
|
}
|
|
190
342
|
|
|
191
|
-
.btn
|
|
343
|
+
.modal-btn:hover {
|
|
192
344
|
background-color: rgba(255, 255, 255, 0.1);
|
|
193
345
|
}
|
|
194
346
|
|
|
@@ -221,59 +373,135 @@
|
|
|
221
373
|
<i class="material-icons">school</i>
|
|
222
374
|
</header>
|
|
223
375
|
|
|
224
|
-
<!--
|
|
225
|
-
<
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
<
|
|
376
|
+
<!-- VIEW 1: Login Screen -->
|
|
377
|
+
<div id="login-view" class="view active">
|
|
378
|
+
<main class="container">
|
|
379
|
+
<div class="card">
|
|
380
|
+
<div class="card-icon-wrapper">
|
|
381
|
+
<i class="material-icons">lock_outline</i>
|
|
382
|
+
</div>
|
|
383
|
+
<h2 class="card-title">Welcome Student</h2>
|
|
384
|
+
<p class="card-subtitle">Please enter your class code to access your study materials and interactive guides.</p>
|
|
385
|
+
|
|
386
|
+
<div class="input-container">
|
|
387
|
+
<input type="text" id="class-code-input" placeholder="e.g. 123456" maxlength="6" autofocus>
|
|
388
|
+
<label for="class-code-input">Class Code</label>
|
|
389
|
+
</div>
|
|
390
|
+
|
|
391
|
+
<div id="error-msg">Invalid class code. Please check with your teacher or instructor.</div>
|
|
392
|
+
|
|
393
|
+
<button class="btn-raised" onclick="verifyCode()">Enter Code</button>
|
|
235
394
|
</div>
|
|
236
|
-
|
|
237
|
-
|
|
395
|
+
</main>
|
|
396
|
+
</div>
|
|
397
|
+
|
|
398
|
+
<!-- VIEW 2: Portal Dashboard -->
|
|
399
|
+
<div id="portal-view" class="view">
|
|
400
|
+
<div class="portal-container">
|
|
401
|
+
<!-- Card 1: Sandboxels -->
|
|
402
|
+
<div class="portal-card">
|
|
403
|
+
<div class="card-media" style="background-color: #00897b;">
|
|
404
|
+
<i class="material-icons">science</i>
|
|
405
|
+
</div>
|
|
406
|
+
<div class="card-content">
|
|
407
|
+
<h2 class="portal-card-title">Sandboxels</h2>
|
|
408
|
+
<p class="card-text">A falling sand and physics sandbox game where you can mix elements, trigger chemical reactions, and experiment on a grid. Great for life science.</p>
|
|
409
|
+
</div>
|
|
410
|
+
<div class="card-actions">
|
|
411
|
+
<button class="btn-flat" onclick="openGame('Sandboxels', 'sandboxels-package/sandboxels-1.13.2/index.html')">Launch App</button>
|
|
412
|
+
</div>
|
|
238
413
|
</div>
|
|
239
|
-
</div>
|
|
240
414
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
415
|
+
<!-- Card 2: HexGL -->
|
|
416
|
+
<div class="portal-card">
|
|
417
|
+
<div class="card-media" style="background-color: #e53935;">
|
|
418
|
+
<i class="material-icons">speed</i>
|
|
419
|
+
</div>
|
|
420
|
+
<div class="card-content">
|
|
421
|
+
<h2 class="portal-card-title">HexGL</h2>
|
|
422
|
+
<p class="card-text">A futuristic 3D WebGL racing game built with HTML5 where you pilot a high-speed craft through complex tracks. Great for testing your shape naming skills.</p>
|
|
423
|
+
</div>
|
|
424
|
+
<div class="card-actions">
|
|
425
|
+
<button class="btn-flat" onclick="openGame('HexGL', 'hexgl-package/HexGL-master/index.html')">Launch App</button>
|
|
426
|
+
</div>
|
|
245
427
|
</div>
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
428
|
+
|
|
429
|
+
<!-- Card 3: ClassiCube -->
|
|
430
|
+
<div class="portal-card">
|
|
431
|
+
<div class="card-media" style="background-color: #00acc1;">
|
|
432
|
+
<i class="material-icons">terrain</i>
|
|
433
|
+
</div>
|
|
434
|
+
<div class="card-content">
|
|
435
|
+
<h2 class="portal-card-title">ClassiCube</h2>
|
|
436
|
+
<p class="card-text">A lightweight multiplayer-compatible classic block building sandbox game. Great for architecture and spatial visualization exercises.</p>
|
|
437
|
+
</div>
|
|
438
|
+
<div class="card-actions">
|
|
439
|
+
<button class="btn-flat" onclick="openGame('ClassiCube', 'classicube-package/index.html')">Launch App</button>
|
|
440
|
+
</div>
|
|
249
441
|
</div>
|
|
250
|
-
|
|
251
|
-
|
|
442
|
+
|
|
443
|
+
<!-- Card 4: 2048 -->
|
|
444
|
+
<div class="portal-card">
|
|
445
|
+
<div class="card-media" style="background-color: #ffb300;">
|
|
446
|
+
<i class="material-icons">grid_on</i>
|
|
447
|
+
</div>
|
|
448
|
+
<div class="card-content">
|
|
449
|
+
<h2 class="portal-card-title">2048</h2>
|
|
450
|
+
<p class="card-text">A classic sliding tile puzzle game where you combine matching numbers to reach the 2048 tile. Great for math logic and strategic thinking.</p>
|
|
451
|
+
</div>
|
|
452
|
+
<div class="card-actions">
|
|
453
|
+
<button class="btn-flat" onclick="openGame('2048', '2048-package/index.html')">Launch App</button>
|
|
454
|
+
</div>
|
|
252
455
|
</div>
|
|
253
456
|
</div>
|
|
254
|
-
|
|
255
|
-
</main>
|
|
457
|
+
</div>
|
|
256
458
|
|
|
257
459
|
<!-- Game Modal Window Overlay -->
|
|
258
460
|
<div id="game-modal">
|
|
259
|
-
<div class="modal-content">
|
|
461
|
+
<div class="modal-content" id="modal-box">
|
|
260
462
|
<div class="modal-header">
|
|
261
463
|
<h3 id="modal-game-title" class="modal-title">Game Window</h3>
|
|
262
|
-
<
|
|
263
|
-
<
|
|
264
|
-
|
|
464
|
+
<div class="modal-header-actions">
|
|
465
|
+
<button class="modal-btn" onclick="toggleFullScreen()" title="Toggle Fullscreen">
|
|
466
|
+
<i class="material-icons" id="fullscreen-icon">fullscreen</i>
|
|
467
|
+
</button>
|
|
468
|
+
<button class="modal-btn" onclick="closeGame()" title="Close Window">
|
|
469
|
+
<i class="material-icons">close</i>
|
|
470
|
+
</button>
|
|
471
|
+
</div>
|
|
265
472
|
</div>
|
|
266
473
|
<div class="modal-body">
|
|
267
|
-
<iframe id="game-iframe" src="" title="Game View"></iframe>
|
|
474
|
+
<iframe id="game-iframe" src="" title="Game View" sandbox="allow-scripts allow-same-origin allow-modals allow-pointer-lock allow-downloads"></iframe>
|
|
268
475
|
</div>
|
|
269
476
|
</div>
|
|
270
477
|
</div>
|
|
271
478
|
|
|
272
479
|
<footer>
|
|
273
|
-
StudyUp •
|
|
480
|
+
StudyUp • Student Resource Portal • 2026
|
|
274
481
|
</footer>
|
|
275
482
|
|
|
276
483
|
<script>
|
|
484
|
+
// Allow pressing 'Enter' to submit code
|
|
485
|
+
document.getElementById('class-code-input').addEventListener('keypress', function (e) {
|
|
486
|
+
if (e.key === 'Enter') {
|
|
487
|
+
verifyCode();
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
function verifyCode() {
|
|
492
|
+
const inputVal = document.getElementById('class-code-input').value.trim();
|
|
493
|
+
const errorMsg = document.getElementById('error-msg');
|
|
494
|
+
|
|
495
|
+
if (inputVal === '814212') {
|
|
496
|
+
errorMsg.style.display = 'none';
|
|
497
|
+
document.getElementById('login-view').classList.remove('active');
|
|
498
|
+
document.getElementById('portal-view').classList.add('active');
|
|
499
|
+
} else {
|
|
500
|
+
errorMsg.style.display = 'block';
|
|
501
|
+
document.getElementById('class-code-input').focus();
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
277
505
|
function openGame(gameName, gameUrl) {
|
|
278
506
|
document.getElementById('modal-game-title').innerText = gameName;
|
|
279
507
|
document.getElementById('game-iframe').src = gameUrl;
|
|
@@ -281,11 +509,38 @@
|
|
|
281
509
|
}
|
|
282
510
|
|
|
283
511
|
function closeGame() {
|
|
512
|
+
// Exit fullscreen if active when closing
|
|
513
|
+
if (document.fullscreenElement) {
|
|
514
|
+
document.exitFullscreen();
|
|
515
|
+
}
|
|
284
516
|
document.getElementById('game-modal').style.display = 'none';
|
|
285
|
-
// Clear iframe src so the game stops running in the background when closed
|
|
286
517
|
document.getElementById('game-iframe').src = '';
|
|
287
518
|
}
|
|
288
|
-
</script>
|
|
289
519
|
|
|
520
|
+
function toggleFullScreen() {
|
|
521
|
+
const modalBox = document.getElementById('modal-box');
|
|
522
|
+
const icon = document.getElementById('fullscreen-icon');
|
|
523
|
+
|
|
524
|
+
if (!document.fullscreenElement) {
|
|
525
|
+
modalBox.requestFullscreen().catch(err => {
|
|
526
|
+
alert(`Error attempting to enable fullscreen: ${err.message}`);
|
|
527
|
+
});
|
|
528
|
+
icon.innerText = 'fullscreen_exit';
|
|
529
|
+
} else {
|
|
530
|
+
document.exitFullscreen();
|
|
531
|
+
icon.innerText = 'fullscreen';
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Keep fullscreen icon updated if user exits via keyboard (Esc)
|
|
536
|
+
document.addEventListener('fullscreenchange', () => {
|
|
537
|
+
const icon = document.getElementById('fullscreen-icon');
|
|
538
|
+
if (!document.fullscreenElement) {
|
|
539
|
+
icon.innerText = 'fullscreen';
|
|
540
|
+
} else {
|
|
541
|
+
icon.innerText = 'fullscreen_exit';
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
</script>
|
|
290
545
|
</body>
|
|
291
546
|
</html>
|