summaryrefslogtreecommitdiff
path: root/master/client/src
diff options
context:
space:
mode:
Diffstat (limited to 'master/client/src')
-rw-r--r--master/client/src/App.vue15
-rw-r--r--master/client/src/components/G7Map.vue85
-rw-r--r--master/client/src/components/MinionStatus.vue110
-rw-r--r--master/client/src/main.ts5
-rw-r--r--master/client/src/router.ts17
-rw-r--r--master/client/src/scss/_breakpoints.scss8
-rw-r--r--master/client/src/scss/_colors.scss3
-rw-r--r--master/client/src/scss/_fonts.scss3
-rw-r--r--master/client/src/shims-vue.d.ts6
-rw-r--r--master/client/src/views/Home.vue53
10 files changed, 305 insertions, 0 deletions
diff --git a/master/client/src/App.vue b/master/client/src/App.vue
new file mode 100644
index 0000000..1638c18
--- /dev/null
+++ b/master/client/src/App.vue
@@ -0,0 +1,15 @@
+<template>
+ <router-view />
+</template>
+
+<style lang="scss">
+@use "scss/colors";
+@use "scss/fonts";
+
+#app {
+ color: colors.$text;
+ background-color: colors.$background;
+ font-family: fonts.$primary;
+}
+
+</style>
diff --git a/master/client/src/components/G7Map.vue b/master/client/src/components/G7Map.vue
new file mode 100644
index 0000000..6a887b1
--- /dev/null
+++ b/master/client/src/components/G7Map.vue
@@ -0,0 +1,85 @@
+<template>
+ <div class="map-wrapper">
+ <img src="g7-map.svg">
+ <div class="rooms">
+ <span class="title">Rooms</span>
+ <ol>
+ <li
+ :key="room"
+ v-for="room in rooms"
+ >
+ {{ room }}
+ </li>
+ </ol>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from "vue";
+
+export default defineComponent(
+ {
+ name: "G7Map",
+ data() {
+ return {
+ rooms: [
+ "Studio / G3",
+ "Studio 1",
+ "Hall",
+ "Studio 2",
+ "Studio 3",
+ "Grupprum",
+ "Verkstad",
+ "Serverrum",
+ "Kurator",
+ "Pannrum",
+ "Toalett",
+ "Inspelningsbås",
+ "G2",
+ "Trapphus"
+ ]
+ };
+ }
+ }
+);
+</script>
+
+<style scoped lang="scss">
+@use "sass:map";
+
+@use "@/scss/colors";
+
+@import "@/scss/breakpoints";
+
+.map-wrapper {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 5em;
+ column-gap: 10em;
+
+ img {
+ max-width: 50%;
+ }
+
+ .rooms {
+ min-width: 40%;
+
+ ol li {
+ line-height: 1.75em;
+ }
+
+ .title {
+ font-size: 2rem;
+ font-weight: 700;
+ color: colors.$primary;
+ }
+ }
+}
+
+@media (max-width: map.get($breakpoints, "xl")) {
+ .map-wrapper img {
+ max-width: 90%;
+ }
+}
+</style>
diff --git a/master/client/src/components/MinionStatus.vue b/master/client/src/components/MinionStatus.vue
new file mode 100644
index 0000000..ec2564c
--- /dev/null
+++ b/master/client/src/components/MinionStatus.vue
@@ -0,0 +1,110 @@
+<template>
+ <div class="minion">
+ <span class="name">{{ name }}</span>
+ <span class="ip">{{ ip }}</span>
+ Temperature: {{ temperature }}
+ </div>
+</template>
+
+<script lang="ts">
+import { ref, defineComponent } from "vue";
+
+interface MinionResponseData {
+ data: { temperature: number } | null,
+ error: string | null
+}
+
+export default defineComponent(
+ {
+ name: "MinionStatus",
+ props: {
+ name: {
+ type: String,
+ required: true
+ },
+ ip: {
+ type: String,
+ required: true
+ }
+ },
+ setup(props) {
+ const temperature = ref("None");
+
+ async function fetch_temperature() {
+ let response: Response;
+
+ try {
+ response = await fetch(`http://${props.ip}`);
+ }
+ catch (err) {
+ const error = err as Error;
+
+ console.error(
+ `Failed to fetch temperature for minion "${props.name}". ` +
+ `${error.message}`
+ );
+ return;
+ }
+
+ const data = await response.json() as MinionResponseData;
+
+ if(!response.ok) {
+ if(data.error !== null) {
+ console.error(
+ `Minion "${props.name}" responded with status ` +
+ `${response.status} and error "${data.error}"`
+ );
+ }
+ else {
+ console.error(
+ `Minion "${props.name}" responded with status ` +
+ `${response.status} and a unknown error`
+ );
+ }
+
+ return;
+ }
+
+ if(data.data == null) {
+ console.error(`Minion "${props.name}" has no data in response`);
+ return;
+ }
+
+ temperature.value = `${data.data.temperature}°C`;
+ }
+
+ return { temperature, fetch_temperature };
+ },
+ created() {
+ this.fetch_temperature();
+ }
+ }
+);
+</script>
+
+<style scoped lang="scss">
+@use "@/scss/colors";
+
+.minion {
+ background-color: lighten(colors.$background, 8%);
+ width: fit-content;
+ padding-top: 1em;
+ padding-bottom: 1.5em;
+ padding-left: 1.5em;
+ padding-right: 3em;
+ border: 1px solid lighten(colors.$background, 14%);
+ border-radius: 8px;
+
+ .name {
+ display: block;
+ font-size: 1.25rem;
+ font-weight: 700;
+ color: colors.$primary;
+ margin-bottom: 0.25em;
+ }
+
+ .ip {
+ display: block;
+ }
+}
+</style>
diff --git a/master/client/src/main.ts b/master/client/src/main.ts
new file mode 100644
index 0000000..10ea69d
--- /dev/null
+++ b/master/client/src/main.ts
@@ -0,0 +1,5 @@
+import { createApp } from "vue";
+import App from "./App.vue";
+import router from "./router";
+
+createApp(App).use(router).mount("#app");
diff --git a/master/client/src/router.ts b/master/client/src/router.ts
new file mode 100644
index 0000000..4c70eab
--- /dev/null
+++ b/master/client/src/router.ts
@@ -0,0 +1,17 @@
+import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
+import HomeView from "./views/Home.vue";
+
+const routes: Array<RouteRecordRaw> = [
+ {
+ path: "/",
+ name: "home",
+ component: HomeView
+ }
+];
+
+const router = createRouter({
+ history: createWebHashHistory(),
+ routes
+});
+
+export default router;
diff --git a/master/client/src/scss/_breakpoints.scss b/master/client/src/scss/_breakpoints.scss
new file mode 100644
index 0000000..fe2ccdb
--- /dev/null
+++ b/master/client/src/scss/_breakpoints.scss
@@ -0,0 +1,8 @@
+$breakpoints: (
+ "xs": 0,
+ "sm": 576px,
+ "md": 768px,
+ "lg": 992px,
+ "xl": 1200px,
+ "xxl": 1400px
+);
diff --git a/master/client/src/scss/_colors.scss b/master/client/src/scss/_colors.scss
new file mode 100644
index 0000000..d8bc4dd
--- /dev/null
+++ b/master/client/src/scss/_colors.scss
@@ -0,0 +1,3 @@
+$text: #ffffff;
+$background: #121212;
+$primary: #118AB2;
diff --git a/master/client/src/scss/_fonts.scss b/master/client/src/scss/_fonts.scss
new file mode 100644
index 0000000..72a9501
--- /dev/null
+++ b/master/client/src/scss/_fonts.scss
@@ -0,0 +1,3 @@
+@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap');
+
+$primary: "Lato", sans-serif;
diff --git a/master/client/src/shims-vue.d.ts b/master/client/src/shims-vue.d.ts
new file mode 100644
index 0000000..3804a43
--- /dev/null
+++ b/master/client/src/shims-vue.d.ts
@@ -0,0 +1,6 @@
+/* eslint-disable */
+declare module '*.vue' {
+ import type { DefineComponent } from 'vue'
+ const component: DefineComponent<{}, {}, any>
+ export default component
+}
diff --git a/master/client/src/views/Home.vue b/master/client/src/views/Home.vue
new file mode 100644
index 0000000..88f65e8
--- /dev/null
+++ b/master/client/src/views/Home.vue
@@ -0,0 +1,53 @@
+<template>
+ <div class="home">
+ <div id="title-container">
+ <span>Gymnasiearbete</span>
+ </div>
+ <!--
+ <div id="minion-list">
+ <Minion
+ name="Skyddsling 1"
+ ip="10.0.1.179"
+ />
+ </div>
+ -->
+ <div id="map-container">
+ <G7Map />
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { Options, Vue } from "vue-class-component";
+import Minion from "@/components/MinionStatus.vue";
+import G7Map from "@/components/G7Map.vue";
+
+@Options({
+ components: {
+ Minion,
+ G7Map
+ }
+})
+export default class HomeView extends Vue {}
+</script>
+
+<style scoped lang="scss">
+#title-container {
+ display: flex;
+ justify-content: center;
+ margin-top: 2em;
+ margin-bottom: 7em;
+
+ span {
+ font-size: 2.5rem;
+ }
+}
+
+#minion-list {
+ margin: 3em;
+}
+
+#map-container {
+ margin-left: 3em;
+}
+</style>