summaryrefslogtreecommitdiff
path: root/master/client/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'master/client/src/components')
-rw-r--r--master/client/src/components/G7Map.vue85
-rw-r--r--master/client/src/components/MinionStatus.vue110
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>