aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorFurkan Sahin <furkan-dev@proton.me>2021-04-10 21:35:13 -0500
committerFurkan Sahin <furkan-dev@proton.me>2021-04-10 21:35:13 -0500
commit74e6cc31e83ad570a9f06765d288e9024736e73f (patch)
treea9757e9ffa099a3d3be5786d20d623e2ce933855 /src/components
parentea8dcfe3bf1ebe84ac483bb91e37ee4faa0d77ea (diff)
Commit MVP
Diffstat (limited to 'src/components')
-rw-r--r--src/components/ActionBar.vue75
-rw-r--r--src/components/FileUpload.vue41
-rw-r--r--src/components/HelloWorld.vue60
-rw-r--r--src/components/List.vue41
4 files changed, 157 insertions, 60 deletions
diff --git a/src/components/ActionBar.vue b/src/components/ActionBar.vue
new file mode 100644
index 0000000..96dbaae
--- /dev/null
+++ b/src/components/ActionBar.vue
@@ -0,0 +1,75 @@
+<template>
+ <div>
+ <file-upload
+ :accept="'text/plain'"
+ :multiple="true"
+ @file-changed="handlePtChange">Upload PT Schedule</file-upload>
+ <file-upload
+ :accept="'application/json'"
+ @file-changed="handleLabChange">Upload Lab Schedule</file-upload>
+ <button @click="save">Export</button>
+ </div>
+</template>
+
+<script>
+import FileUpload from '@/components/FileUpload.vue';
+
+import { parseLabFile, parsePtSchedule } from '@/features/parser';
+
+export default {
+ name: 'ActionBar',
+ components: {
+ FileUpload,
+ },
+ methods: {
+ handleLabChange(files) {
+ parseLabFile(files[0])
+ .then((data) => {
+ this.$store.commit('importLabs', data);
+ })
+ .catch((error) => {
+ console.error(error);
+ });
+ },
+ handlePtChange(files) {
+ const result = [];
+ const promises = [];
+
+ files.forEach((file) => {
+ const p = parsePtSchedule(file).then((data) => result.push(data));
+ promises.push(p);
+ });
+
+ Promise.all(promises)
+ .then(() => {
+ this.$store.commit('addPeerTeachers', result);
+ });
+ },
+ save() {
+ const database = {
+ labs: Object.fromEntries(this.$store.state.labs),
+ peerTeachers: Object.fromEntries(this.$store.state.peerTeachers),
+ };
+
+ const jsonObj = JSON.stringify(database, (_, value) => {
+ if (typeof value === 'object' && value instanceof Set) {
+ return [...value];
+ }
+ return value;
+ });
+
+ const blob = new Blob([jsonObj], { type: 'text/json' });
+ const anchor = document.createElement('a');
+ const url = window.URL.createObjectURL(blob);
+ anchor.href = url;
+ anchor.download = 'pt-db.json';
+ anchor.style = 'display: none';
+
+ document.body.appendChild(anchor);
+ anchor.click();
+ document.body.removeChild(anchor);
+ window.URL.revokeObjectURL(url);
+ },
+ },
+};
+</script>
diff --git a/src/components/FileUpload.vue b/src/components/FileUpload.vue
new file mode 100644
index 0000000..b2fdb14
--- /dev/null
+++ b/src/components/FileUpload.vue
@@ -0,0 +1,41 @@
+<template>
+ <label class="file-upload-lbl">
+ <input
+ type="file"
+ :accept="accept"
+ @change="$emit('fileChanged', $event.target.files)"
+ :multiple="multiple" hidden />
+ <slot>Upload</slot>
+ </label>
+</template>
+
+<script>
+export default {
+ name: 'FileUpload',
+ props: {
+ accept: String,
+ multiple: {
+ type: Boolean,
+ default: false,
+ },
+ },
+ emits: {
+ selectionChanged: null,
+ },
+};
+</script>
+
+<style scoped>
+.file-upload-lbl {
+ background-color: #500000;
+ color: white;
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ padding: 5px;
+ text-align: center;
+}
+
+.file-upload-lbl:hover {
+ color: grey;
+ cursor: pointer;
+}
+</style>
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
deleted file mode 100644
index 94ceb6b..0000000
--- a/src/components/HelloWorld.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
- <div class="hello">
- <h1>{{ msg }}</h1>
- <p>
- For a guide and recipes on how to configure / customize this project,<br>
- check out the
- <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
- </p>
- <h3>Installed CLI Plugins</h3>
- <ul>
- <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
- <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
- <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
- <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
- </ul>
- <h3>Essential Links</h3>
- <ul>
- <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
- <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
- <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
- <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
- <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
- </ul>
- <h3>Ecosystem</h3>
- <ul>
- <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
- <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
- <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
- <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
- <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
- </ul>
- </div>
-</template>
-
-<script>
-export default {
- name: 'HelloWorld',
- props: {
- msg: String,
- },
-};
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-h3 {
- margin: 40px 0 0;
-}
-ul {
- list-style-type: none;
- padding: 0;
-}
-li {
- display: inline-block;
- margin: 0 10px;
-}
-a {
- color: #42b983;
-}
-</style>
diff --git a/src/components/List.vue b/src/components/List.vue
new file mode 100644
index 0000000..031f708
--- /dev/null
+++ b/src/components/List.vue
@@ -0,0 +1,41 @@
+<template>
+ <ul class="list">
+ <li
+ v-for="item in items"
+ :key="item.id"
+ @click="$emit('selectionChanged', item)"
+ class="list-item">
+ <slot :item="item">{{ item }}</slot>
+ </li>
+ </ul>
+</template>
+
+<script>
+export default {
+ name: 'List',
+ props: {
+ items: Array,
+ },
+ emits: {
+ selectionChanged: null,
+ },
+};
+</script>
+
+<style scoped>
+.list {
+ list-style-type: none;
+}
+
+.list-item {
+ border: 1px solid grey;
+ border-radius: 5px;
+ margin: 5px 0;
+ padding: 0.15em;
+ text-align: center;
+}
+
+.list-item:hover {
+ background-color: rgb(182, 182, 182);
+}
+</style>