diff options
Diffstat (limited to 'master/client/src')
-rw-r--r-- | master/client/src/App.vue | 15 | ||||
-rw-r--r-- | master/client/src/components/G7Map.vue | 85 | ||||
-rw-r--r-- | master/client/src/components/MinionStatus.vue | 110 | ||||
-rw-r--r-- | master/client/src/main.ts | 5 | ||||
-rw-r--r-- | master/client/src/router.ts | 17 | ||||
-rw-r--r-- | master/client/src/scss/_breakpoints.scss | 8 | ||||
-rw-r--r-- | master/client/src/scss/_colors.scss | 3 | ||||
-rw-r--r-- | master/client/src/scss/_fonts.scss | 3 | ||||
-rw-r--r-- | master/client/src/shims-vue.d.ts | 6 | ||||
-rw-r--r-- | master/client/src/views/Home.vue | 53 |
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> |