Added Roles, User Management, fixed bugs, added FlexTable component (should be renamed to GridTable), other table components and test code should be removed down the line, added admin function to fix broken data structures.
This commit is contained in:
@@ -1,32 +1,187 @@
|
||||
|
||||
<style>
|
||||
nav {
|
||||
font-size: 2rem;
|
||||
a.button {
|
||||
background: #7171ec;
|
||||
border-radius: 999px;
|
||||
box-shadow: #5E5DF0 0 10px 20px -10px;
|
||||
box-sizing: border-box;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-family: Inter,Helvetica,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Noto Color Emoji","Segoe UI Symbol","Android Emoji",EmojiSymbols,-apple-system,system-ui,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans",sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 24px;
|
||||
opacity: 1;
|
||||
outline: 0 solid transparent;
|
||||
padding: 8px 18px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
touch-action: manipulation;
|
||||
width: fit-content;
|
||||
word-break: break-word;
|
||||
border: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
a {
|
||||
display: block;
|
||||
color: green;
|
||||
text-decoration: none;
|
||||
input {
|
||||
--background: #fff;
|
||||
--border-default: #D0D0DF;
|
||||
--border-active: #3D6DF9;
|
||||
/*--shadow-default: #{rgba(#202048, .12)};*/
|
||||
/*--shadow-active: #{rgba(#3D6DF9, .25)};*/
|
||||
--text-color: #818190;
|
||||
--placeholder-color: #C9C9D9;
|
||||
--placeholder-color-hover: #BABAC9;
|
||||
--close: #818190;
|
||||
--close-light: #BABAC9;
|
||||
--close-background: #F1F1FA;
|
||||
width: 100%;
|
||||
max-width: 240px;
|
||||
border-radius: 8px;
|
||||
box-shadow: inset 0 0 0 1px;
|
||||
}
|
||||
|
||||
.options {
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import {Route} from 'tinro';
|
||||
import {Route, router, meta} from 'tinro';
|
||||
import ChromebookScan from './ChromebookScan.svelte';
|
||||
import {Meteor} from "meteor/meteor";
|
||||
|
||||
$: serialInput = null;
|
||||
$: emailInput = null;
|
||||
function serialSearch() {
|
||||
router.goto("/chromebooks?serial=" + encodeURIComponent(serialInput) + "®ex=true");
|
||||
}
|
||||
function emailSearch() {
|
||||
router.goto("/chromebooks?email=" + encodeURIComponent(emailInput) + "®ex=true");
|
||||
}
|
||||
|
||||
// console.log("Loading Script");
|
||||
// //Attempt to listen for URL changes (query portion specifically).
|
||||
// (function(history){
|
||||
// const pushState = history.pushState;
|
||||
// history.pushState = function(state) {
|
||||
// if (typeof history.onpushstate == "function") {
|
||||
// history.onpushstate({state: state});
|
||||
// }
|
||||
// // Call your custom function here
|
||||
// console.log("Push state");
|
||||
// console.log(history);
|
||||
// console.log(arguments);
|
||||
// return pushState.apply(history, arguments);
|
||||
// }
|
||||
// })(window.history);
|
||||
|
||||
// const params = Object.fromEntries(new URLSearchParams(window.location.search));
|
||||
//
|
||||
// console.log("Params: ");
|
||||
// console.log(params);
|
||||
|
||||
$: deviceId = null;
|
||||
$: serial = null;
|
||||
$: email = null
|
||||
$: regex = false;
|
||||
$: router.subscribe(query => {
|
||||
deviceId = router.location.query.get("deviceId");
|
||||
serial = router.location.query.get("serial");
|
||||
email = router.location.query.get("email");
|
||||
regex = router.location.query.get("regex");
|
||||
|
||||
if(deviceId) deviceId = decodeURIComponent(deviceId);
|
||||
if(serial) serial = decodeURIComponent(serial);
|
||||
if(email) email = decodeURIComponent(email);
|
||||
if(regex) regex = true;
|
||||
|
||||
// console.log("Query:");
|
||||
// console.log(deviceId);
|
||||
// console.log(serial);
|
||||
// console.log(email);
|
||||
});
|
||||
$: chromebookData = null;
|
||||
$: {
|
||||
if(deviceId || serial || email) {
|
||||
let params = {};
|
||||
|
||||
if(deviceId) params.deviceId = deviceId;
|
||||
else if(serial) params.serial = serial;
|
||||
else if(email) params.email = email;
|
||||
|
||||
if(regex) params.regex = true;
|
||||
|
||||
Meteor.call("DataCollection.chromebookData", params, (error, result) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
chromebookData = result;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
chromebookData = null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Route path="/">
|
||||
<div className="container">
|
||||
<div class="row">
|
||||
<nav class="col-12 center">
|
||||
<h1>Chromebook Management</h1>
|
||||
<a href="chromebooks/scan">Scan A Chromebook</a>
|
||||
<a href="chromebooks/byStudent">Chromebook History By Student</a>
|
||||
<a href="chromebooks/byChromebook">Chromebook History By Chromebook</a>
|
||||
</nav>
|
||||
<Route path="/" let:meta>
|
||||
{#if chromebookData}
|
||||
<div class="container">
|
||||
<div class="row col-12">
|
||||
<ul>
|
||||
{#each chromebookData as data}
|
||||
<li><a href="/chromebooks?email={encodeURIComponent(data.email)}">{data.email}</a><br/>
|
||||
<a href="/chromebooks?deviceId={encodeURIComponent(data.deviceId)}">{data.deviceId}</a><br/>
|
||||
<a href="/chromebooks?serial={encodeURIComponent(data.serial)}">{data.serial}</a><br/>
|
||||
{new Date(data.startTime).toLocaleDateString("en-US") + "-" + new Date(data.endTime).toLocaleDateString("en-US")}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="container">
|
||||
<div class="row col-12">
|
||||
<div class="options">
|
||||
<h1>Chromebook Management</h1>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
By Chromebook Device ID: <a href="/chromebooks/scan" className="button">Scan</a>
|
||||
</li>
|
||||
<li>
|
||||
By Chromebook Serial Number: <br/>
|
||||
<input type="text" bind:value="{serialInput}" placeholder="Serial Number"/><br/>
|
||||
<button type="button" role="button" on:click={serialSearch}>Search</button>
|
||||
</li>
|
||||
<li>
|
||||
By Email Address: <br/>
|
||||
<input type="text" bind:value="{emailInput}" placeholder="Email"/>@avpanthers.org<br/>
|
||||
<button type="button" role="button" on:click={emailSearch}>Search</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</Route>
|
||||
|
||||
<Route path="/byDevice/:deviceId">
|
||||
<div class="container">
|
||||
<div class="row col-12">
|
||||
<ul>
|
||||
{#each chromebookData as data}
|
||||
<li>{data.email}<br/>{data.serial}
|
||||
<br/>{new Date(data.startTime).toLocaleDateString("en-US") + "-" + new Date(data.endTime).toLocaleDateString("en-US")}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</Route>
|
||||
|
||||
<Route path="/scan">
|
||||
<ChromebookScan/>
|
||||
</Route>
|
||||
|
||||
Reference in New Issue
Block a user