Skip to content

Instantly share code, notes, and snippets.

@mattattui
Last active July 12, 2017 14:28
Show Gist options
  • Save mattattui/5c035ce6d9eef514754339bb02d283b8 to your computer and use it in GitHub Desktop.
Save mattattui/5c035ce6d9eef514754339bb02d283b8 to your computer and use it in GitHub Desktop.
API Status component

Call it like this:

<api-status theme="dark" status-endpoint="/api/status"></api-status>

It uses window.fetch() which you might have to polyfill if you haven't already: yarn add whatwg-fetch

The component expects a JSON response with a property called message. If it's non-empty, it'll show the message. Pretty straightforward.

<template>
<div :class="$style.wrapper" v-if="message">
<div :class="getStyles">
{{ message }}
<span :class="$style.close" @click="message = ''">
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Ctitle%3Ex%3C/title%3E%3Cpath stroke-width='5' stroke='%23F00' d='M9.8 9.8l-8 8 8-8-8-8 8 8 8-8-8 8 8 8z' fill='none'/%3E%3C/svg%3E">
</span>
</div>
</div>
</template>
<style module>
@keyframes swing-in-top-fwd {
0% {
transform: rotateX(-100deg);
transform-origin: top;
opacity: 0;
}
100% {
transform: rotateX(0deg);
transform-origin: top;
opacity: 1;
}
}
.wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 10000;
}
.banner {
max-width: 100%;
width: 45rem;
padding: .5rem;
font-size: 16px;
font-family: sans-serif;
margin-left: auto;
margin-right: auto;
text-align: center;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
position: relative;
animation: swing-in-top-fwd 0.5s cubic-bezier(0.175, 0.885, 0.320, 1.275) both;
}
.close {
position: absolute;
top: 8px;
right: 8px;
cursor: pointer;
display: block;
}
.light {
background: #F0EDEB;
color: #333;
}
.dark {
background: #333;
color: #F0EDEB;
}
</style>
<script>
export default {
name: 'api-status',
props: ['theme', 'statusEndpoint'],
data() {
return {
message: '',
};
},
created() {
fetch(this.statusEndpoint, {
credentials: 'include',
})
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error('Unexpected network response');
})
.then((data) => {
this.message = data.message;
})
.catch(() => {
this.message = '';
});
},
computed: {
getStyles() {
const styles = [this.$style.banner];
switch (this.theme) {
case 'dark':
styles.push(this.$style.dark);
break;
case 'light':
default:
styles.push(this.$style.light);
break;
}
return styles;
},
},
};
</script>
@mattattui
Copy link
Author

To use this on non-Vue projects, make sure you have vue-cli installed, save the component above into a file (e.g. api-status.vue) then run vue build --prod --lib ApiStatus api-status.vue. This will create a dist folder containing minified JS and CSS files.

In your project, open up your HTML file (e.g. index.html) and add to the head:

<link rel="stylesheet" href="path/to/api-status.css">

To the body, add something like this:

<span id="statusApp"><api-status theme="dark" status-endpoint="path/to/status-endpoint"></api-status></span>
<script src="https://vuejs.org/js/vue.min.js"></script>
<script src="path/to/api-status.js"></script>
<script>
var statusApp = new Vue({ el: '#statusApp', components: { ApiStatus: ApiStatus } });
</script>

@mattattui
Copy link
Author

Oh and if you're looking for a license: CC-Zero https://creativecommons.org/publicdomain/zero/1.0/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment