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/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
- /* Main Container & Grid */
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
- /* Material Card Component */
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
- .btn-close {
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: 4px;
338
+ padding: 6px;
187
339
  border-radius: 50%;
188
340
  transition: background-color 0.2s;
189
341
  }
190
342
 
191
- .btn-close:hover {
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
- <!-- Content Grid -->
225
- <main class="container">
226
-
227
- <!-- Card 1: Sandboxels -->
228
- <div class="card">
229
- <div class="card-media" style="background-color: #00897b;">
230
- <i class="material-icons">science</i>
231
- </div>
232
- <div class="card-content">
233
- <h2 class="card-title">Sandboxels</h2>
234
- <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>
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
- <div class="card-actions">
237
- <button class="btn-flat" onclick="openGame('Sandboxels', 'sandboxels-package/sandboxels-1.13.2/index.html')">Launch App</button>
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
- <!-- Card 2: HexGL -->
242
- <div class="card">
243
- <div class="card-media" style="background-color: #e53935;">
244
- <i class="material-icons">speed</i>
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
- <div class="card-content">
247
- <h2 class="card-title">HexGL</h2>
248
- <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>
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
- <div class="card-actions">
251
- <button class="btn-flat" onclick="openGame('HexGL', 'hexgl-package/HexGL-master/index.html')">Launch App</button>
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
- <button class="btn-close" onclick="closeGame()" title="Close Window">
263
- <i class="material-icons">close</i>
264
- </button>
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 &bull; Powered by Knowlage &bull; Material Design 1
480
+ StudyUp &bull; Student Resource Portal &bull; 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>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "studyup",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "StudyUp Game Portal",
5
5
  "main": "index.html",
6
6
  "scripts": {
@@ -12,4 +12,4 @@
12
12
  ],
13
13
  "author": "",
14
14
  "license": "ISC"
15
- }
15
+ }