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>  | 
