diff options
Diffstat (limited to 'master/client/src/components')
-rw-r--r-- | master/client/src/components/G7Map.vue | 85 | ||||
-rw-r--r-- | master/client/src/components/MinionStatus.vue | 110 |
2 files changed, 195 insertions, 0 deletions
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> |