Change lint rules to AirBnB

This commit is contained in:
Alicia Sykes
2019-09-01 13:38:13 +01:00
parent 7ffc35afb6
commit 335c8eec53
18 changed files with 704 additions and 663 deletions

View File

@@ -7,14 +7,14 @@
</template>
<script>
import Footer from '@/components/Footer.vue'
import Footer from '@/components/Footer.vue';
export default {
name: 'app',
components: {
Footer
}
}
Footer,
},
};
</script>
<style lang="scss">

View File

@@ -1,108 +1,108 @@
<template>
<div class="collapsable">
<input :id="`collapsible-${uniqueKey}`" class="toggle" type="checkbox" checked>
<label :for="`collapsible-${uniqueKey}`" class="lbl-toggle" tabindex="0">
<h2>{{ title }}</h2>
</label>
<div class="collapsible-content">
<div class="content-inner">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CollapsableContainer',
props: {
uniqueKey: String,
title: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.collapsable {
width: 310px;
padding: 5px;
margin: 10px;
border-radius: 10px;
background: #1CA8DD;
background: -webkit-linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
background: linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
box-shadow: 1px 1px 2px #130f23;
.wrap-collabsible {
margin-bottom: 1.2rem 0;
}
input[type='checkbox'] {
display: none;
}
label {
outline: none;
}
.lbl-toggle {
display: block;
padding: 1rem;
cursor: pointer;
border-radius: 7px;
transition: all 0.25s ease-out;
text-align: left;
color: #2f323ae6;
h2 {
margin: 0;
padding: 0;
display: inline;
}
}
.lbl-toggle:hover {
color: #2f323a;
}
.lbl-toggle::before {
content: ' ';
display: inline-block;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid currentColor;
vertical-align: middle;
margin-right: .7rem;
transform: translateY(-2px);
transition: transform .2s ease-out;
}
.toggle:checked + .lbl-toggle::before {
transform: rotate(90deg) translateX(-3px);
}
.collapsible-content {
max-height: 0px;
overflow: hidden;
transition: max-height .25s ease-in-out;
background: #2f323ae6;
border-radius: 0 0 10px 10px;
}
.toggle:checked + .lbl-toggle + .collapsible-content {
max-height: 1000px;
}
.toggle:checked + .lbl-toggle {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.collapsible-content .content-inner {
padding: 0.5rem;
}
}
</style>
<template>
<div class="collapsable">
<input :id="`collapsible-${uniqueKey}`" class="toggle" type="checkbox" checked>
<label :for="`collapsible-${uniqueKey}`" class="lbl-toggle" tabindex="0">
<h2>{{ title }}</h2>
</label>
<div class="collapsible-content">
<div class="content-inner">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CollapsableContainer',
props: {
uniqueKey: String,
title: String,
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.collapsable {
width: 310px;
padding: 5px;
margin: 10px;
border-radius: 10px;
background: #1CA8DD;
background: -webkit-linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
background: linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
box-shadow: 1px 1px 2px #130f23;
.wrap-collabsible {
margin-bottom: 1.2rem 0;
}
input[type='checkbox'] {
display: none;
}
label {
outline: none;
}
.lbl-toggle {
display: block;
padding: 1rem;
cursor: pointer;
border-radius: 7px;
transition: all 0.25s ease-out;
text-align: left;
color: #2f323ae6;
h2 {
margin: 0;
padding: 0;
display: inline;
}
}
.lbl-toggle:hover {
color: #2f323a;
}
.lbl-toggle::before {
content: ' ';
display: inline-block;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid currentColor;
vertical-align: middle;
margin-right: .7rem;
transform: translateY(-2px);
transition: transform .2s ease-out;
}
.toggle:checked + .lbl-toggle::before {
transform: rotate(90deg) translateX(-3px);
}
.collapsible-content {
max-height: 0px;
overflow: hidden;
transition: max-height .25s ease-in-out;
background: #2f323ae6;
border-radius: 0 0 10px 10px;
}
.toggle:checked + .lbl-toggle + .collapsible-content {
max-height: 1000px;
}
.toggle:checked + .lbl-toggle {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.collapsible-content .content-inner {
padding: 0.5rem;
}
}
</style>

View File

@@ -1,118 +1,119 @@
<template>
<section>
<form>
<label for="filter-tiles">Search</label>
<input
id="filter-tiles"
v-model="input"
ref="filter"
placeholder="Start typing to filter tiles..."
v-on:input="userIsTypingSomething"
@keydown.esc="clearFilterInput" />
<i v-if="input.length > 0"
class="el-icon-circle-close clear-search"
title="Clear search"
@click="clearFilterInput"></i>
</form>
<div class="space-filler"></div>
</section>
</template>
<script>
export default {
name: 'FilterTile',
data () {
return {
input: ''
}
},
methods: {
userIsTypingSomething () {
this.$emit('user-is-searchin', this.input)
},
clearFilterInput () {
this.input = ''
this.userIsTypingSomething()
document.activeElement.blur()
},
},
mounted: function() {
window.addEventListener('keyup', (event) => {
const key = event.key
if(/^[a-zA-Z]$/.test(key) && !document.activeElement.id) {
this.input += key
this.$refs.filter.focus()
this.userIsTypingSomething()
}
});
}
}
</script>
<style scoped lang="scss">
section {
display: flex;
align-items: center;
align-items: stretch;
background: linear-gradient(0deg, rgba(47,50,58,1) 0%, rgba(40,42,50,1) 100%);
}
form {
border-radius: 0 0 20px 0;
padding: 0 0.2rem 0.2rem 0;
background: #282a32;
label {
display: inline;
background: -webkit-gradient(linear, right bottom, left top, from(#9F86FF), color-stop(#1CA8DD), to(#007AE1));
background: linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0.5rem;
display: inline;
}
input {
display: inline-block;
width: 200px;
padding: 0.5rem;
margin: 0.5rem;
outline: none;
border: none;
border-radius: 12px;
background: #607d8b33;
box-shadow: 1px 1px 2px #232323;
color: #1CA8DD;
font-family: 'Comfortaa', cursive;
&:focus {
background: #607d8b4a;
}
}
.clear-search {
position: absolute;
margin: 1em 0 0 -2em;
color: #1CA8DD;
opacity: 0.5;
border-radius: 50px;
cursor: pointer;
&:hover {
opacity: 1;
background: #282a32;
}
}
}
.space-filler {
flex: 1;
border-radius: 20px 0 0;
background: #2f323a;
}
@media screen and (max-width: 600px) {
form {
flex: 1;
border-radius: 0;
text-align: center;
padding: 0.25rem 0;
}
.space-filler {
display: none;
}
}
</style>
<template>
<section>
<form>
<label for="filter-tiles">Search</label>
<input
id="filter-tiles"
v-model="input"
ref="filter"
placeholder="Start typing to filter tiles..."
v-on:input="userIsTypingSomething"
@keydown.esc="clearFilterInput" />
<i v-if="input.length > 0"
class="el-icon-circle-close clear-search"
title="Clear search"
@click="clearFilterInput"></i>
</form>
<div class="space-filler"></div>
</section>
</template>
<script>
export default {
name: 'FilterTile',
data() {
return {
input: '',
};
},
methods: {
userIsTypingSomething() {
this.$emit('user-is-searchin', this.input);
},
clearFilterInput() {
this.input = '';
this.userIsTypingSomething();
document.activeElement.blur();
},
},
mounted() {
window.addEventListener('keyup', (event) => {
const { key } = event;
if (/^[a-zA-Z]$/.test(key) && !document.activeElement.id) {
this.input += key;
this.$refs.filter.focus();
this.userIsTypingSomething();
}
});
},
};
</script>
<style scoped lang="scss">
section {
display: flex;
align-items: center;
align-items: stretch;
background: linear-gradient(0deg, rgba(47,50,58,1) 0%, rgba(40,42,50,1) 100%);
}
form {
border-radius: 0 0 20px 0;
padding: 0 0.2rem 0.2rem 0;
background: #282a32;
label {
display: inline;
background: -webkit-gradient(
linear, right bottom, left top, from(#9F86FF), color-stop(#1CA8DD), to(#007AE1));
background: linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0.5rem;
display: inline;
}
input {
display: inline-block;
width: 200px;
padding: 0.5rem;
margin: 0.5rem;
outline: none;
border: none;
border-radius: 12px;
background: #607d8b33;
box-shadow: 1px 1px 2px #232323;
color: #1CA8DD;
font-family: 'Comfortaa', cursive;
&:focus {
background: #607d8b4a;
}
}
.clear-search {
position: absolute;
margin: 1em 0 0 -2em;
color: #1CA8DD;
opacity: 0.5;
border-radius: 50px;
cursor: pointer;
&:hover {
opacity: 1;
background: #282a32;
}
}
}
.space-filler {
flex: 1;
border-radius: 20px 0 0;
background: #2f323a;
}
@media screen and (max-width: 600px) {
form {
flex: 1;
border-radius: 0;
text-align: center;
padding: 0.25rem 0;
}
.space-filler {
display: none;
}
}
</style>

View File

@@ -1,41 +1,41 @@
<template>
<footer>
Developed by <a :href="authorUrl">{{authorName}}</a>.
Licensed under <a :href="licenseUrl">{{license}}</a>
{{ showCopyright? '©': '' }} {{date}}.
Get the <a :href="repoUrl">Source Code</a>.
</footer>
</template>
<script>
export default {
name: 'Footer',
props: {
authorName: { type: String, default: 'Alicia Sykes' },
authorUrl: { type: String, default: 'https://aliciasykes.com' },
license: { type: String, default: 'MIT' },
licenseUrl: { type: String, default: 'https://gist.github.com/Lissy93/143d2ee01ccc5c052a17' },
date: { type: String, default: `${new Date().getFullYear()}` },
showCopyright: { type: Boolean, default: true },
repoUrl: { type: String, default: 'https://github.com/lissy93/panel' }
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
footer {
padding: 0.5rem;
text-align: center;
color: #5e6474;
}
footer a{
color: #5e6474;
&:hover {
color: #9F86FF;
}
}
</style>
<template>
<footer>
Developed by <a :href="authorUrl">{{authorName}}</a>.
Licensed under <a :href="licenseUrl">{{license}}</a>
{{ showCopyright? '©': '' }} {{date}}.
Get the <a :href="repoUrl">Source Code</a>.
</footer>
</template>
<script>
export default {
name: 'Footer',
props: {
authorName: { type: String, default: 'Alicia Sykes' },
authorUrl: { type: String, default: 'https://aliciasykes.com' },
license: { type: String, default: 'MIT' },
licenseUrl: { type: String, default: 'https://gist.github.com/Lissy93/143d2ee01ccc5c052a17' },
date: { type: String, default: `${new Date().getFullYear()}` },
showCopyright: { type: Boolean, default: true },
repoUrl: { type: String, default: 'https://github.com/lissy93/panel' },
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
footer {
padding: 0.5rem;
text-align: center;
color: #5e6474;
}
footer a{
color: #5e6474;
&:hover {
color: #9F86FF;
}
}
</style>

View File

@@ -1,33 +1,34 @@
<template>
<header>
<PageTitle />
<Nav class="nav"/>
</header>
</template>
<script>
import PageTitle from '@/components/PageTitle.vue'
import Nav from '@/components/Nav.vue'
export default {
name: 'Header',
components: {
PageTitle,
Nav
}
}
</script>
<style scoped lang="scss">
header {
margin: 0;
padding: 0.5rem;
display: flex;
justify-content: space-between;
background: #282a32;
align-items: center;
align-content: flex-start;
@media screen and (max-width: 600px) {
flex-direction: column-reverse;
}
}
</style>
<template>
<header>
<PageTitle />
<Nav class="nav"/>
</header>
</template>
<script>
import PageTitle from '@/components/PageTitle.vue';
import Nav from '@/components/Nav.vue';
export default {
name: 'Header',
components: {
PageTitle,
Nav,
},
};
</script>
<style scoped lang="scss">
header {
margin: 0;
padding: 0.5rem;
display: flex;
justify-content: space-between;
background: #282a32;
align-items: center;
align-content: flex-start;
@media screen and (max-width: 600px) {
flex-direction: column-reverse;
}
}
</style>

View File

@@ -9,9 +9,9 @@
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
msg: String,
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->

View File

@@ -1,136 +1,134 @@
<template>
<el-tooltip placement="bottom" effect="dark" :content="description" :disabled="!description">
<div class="item" tabindex="0">
<div class="tile-title" :id="`tile-${id}`">
<span class="text">{{ title }}</span>
<div class="overflow-dots">...</div>
</div>
<img
v-if="icon"
:src="`/img/tile-icons/${icon}.png`"
class="tile-icon"
/>
</div>
</el-tooltip>
</template>
<script>
export default {
name: 'Item',
props: {
id: String, // The unique ID of a tile (e.g. 001)
title: String, // The main text of tile, required
subtitle: String, // Optional sub-text
description: String, // Optional tooltip hover text
icon: String, // Optional path to icon, within public/img/tile-icons
color: String, // Optional background color, specified in hex code
url: String, // URL to the resource, optional but recommended
openingMethod: { // Where resource will open, either 'newtab', 'sametab' or 'iframe'
type: String,
default: 'newtab',
validator: (value) =>
['newtab', 'sametab', 'iframe'].indexOf(value) !== -1
}
},
data () {
return { getId: this.id }
},
mounted () {
// Detects overflowing text, and allows is to marguee on hover
// The below code is horifically bad, it is embarassing that I wrote it...
const tileElem = document.getElementById(`tile-${this.getId}`)
if (tileElem) {
const isOverflowing =
tileElem.scrollHeight > tileElem.clientHeight ||
tileElem.scrollWidth > tileElem.clientWidth
if (isOverflowing) {
tileElem.className += ' is-overflowing'
}
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.item {
width: 120px;
height: 100px;
color: #1CA8DD;
display: inline-block;
vertical-align: middle;
margin: 8px;
background: #607d8b33;
text-align: center;
padding: 2px;
border: 2px solid transparent;
border-radius: 10px;
box-shadow: 1px 1px 2px #373737;
cursor: pointer;
&:hover {
box-shadow: 1px 2px 4px #373737;
background: #607d8b4d;
}
&:focus {
border: 2px solid #1CA8DD;
outline: none;
}
}
.tile-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 120px;
height: 30px;
overflow: hidden;
position: relative;
padding: 0;
span.text {
position: absolute;
white-space: nowrap;
transition: 1s;
float: left;
left: 0;
}
&:not(.is-overflowing) span.text{
width: 100%;
}
.overflow-dots {
// display: none;
opacity: 0;
}
}
.tile-title.is-overflowing {
span.text {
overflow: hidden;
}
.overflow-dots {
display: block;
opacity: 1;
background: #354857;
position: absolute;
z-index: 5;
right: 0;
transition: opacity 0.1s ease-in;
}
}
.item:hover .tile-title{
.overflow-dots {
// display: none;
opacity: 0;
}
span.text {
transform: translateX(calc(120px - 100%));
}
}
.tile-icon {
width: 60px;
}
</style>
<template>
<el-tooltip placement="bottom" effect="dark" :content="description" :disabled="!description">
<div class="item" tabindex="0">
<div class="tile-title" :id="`tile-${id}`">
<span class="text">{{ title }}</span>
<div class="overflow-dots">...</div>
</div>
<img
v-if="icon"
:src="`/img/tile-icons/${icon}.png`"
class="tile-icon"
/>
</div>
</el-tooltip>
</template>
<script>
export default {
name: 'Item',
props: {
id: String, // The unique ID of a tile (e.g. 001)
title: String, // The main text of tile, required
subtitle: String, // Optional sub-text
description: String, // Optional tooltip hover text
icon: String, // Optional path to icon, within public/img/tile-icons
color: String, // Optional background color, specified in hex code
url: String, // URL to the resource, optional but recommended
openingMethod: { // Where resource will open, either 'newtab', 'sametab' or 'iframe'
type: String,
default: 'newtab',
validator: (value) => ['newtab', 'sametab', 'iframe'].indexOf(value) !== -1,
},
},
data() {
return { getId: this.id };
},
mounted() {
// Detects overflowing text, and allows is to marguee on hover
// The below code is horifically bad, it is embarassing that I wrote it...
const tileElem = document.getElementById(`tile-${this.getId}`);
if (tileElem) {
const isOverflowing = tileElem.scrollHeight > tileElem.clientHeight
|| tileElem.scrollWidth > tileElem.clientWidth;
if (isOverflowing) {
tileElem.className += ' is-overflowing';
}
}
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.item {
width: 120px;
height: 100px;
color: #1CA8DD;
display: inline-block;
vertical-align: middle;
margin: 8px;
background: #607d8b33;
text-align: center;
padding: 2px;
border: 2px solid transparent;
border-radius: 10px;
box-shadow: 1px 1px 2px #373737;
cursor: pointer;
&:hover {
box-shadow: 1px 2px 4px #373737;
background: #607d8b4d;
}
&:focus {
border: 2px solid #1CA8DD;
outline: none;
}
}
.tile-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 120px;
height: 30px;
overflow: hidden;
position: relative;
padding: 0;
span.text {
position: absolute;
white-space: nowrap;
transition: 1s;
float: left;
left: 0;
}
&:not(.is-overflowing) span.text{
width: 100%;
}
.overflow-dots {
// display: none;
opacity: 0;
}
}
.tile-title.is-overflowing {
span.text {
overflow: hidden;
}
.overflow-dots {
display: block;
opacity: 1;
background: #354857;
position: absolute;
z-index: 5;
right: 0;
transition: opacity 0.1s ease-in;
}
}
.item:hover .tile-title{
.overflow-dots {
// display: none;
opacity: 0;
}
span.text {
transform: translateX(calc(120px - 100%));
}
}
.tile-icon {
width: 60px;
}
</style>

View File

@@ -1,55 +1,55 @@
<template>
<Collapsable :title="title" :uniqueKey="groupId">
<div v-if="!items || items.length < 1" class="no-items">
No Items to Show Yet
</div>
<div v-else class="there-are-items">
<Item
v-for="item in items"
:key="`${groupId}-${item.id}`"
:id="`${groupId}-${item.id}`"
:title="item.title"
:description="item.description"
:icon="item.icon"
/>
</div>
</Collapsable>
</template>
<script>
import Item from '@/components/Item.vue'
import Collapsable from '@/components/Collapsable.vue'
export default {
name: 'ItemGroup',
props: {
groupId: String,
title: String,
items: Array
},
components: {
Collapsable,
Item
}
}
</script>
<style scoped lang="scss">
.no-items {
width: 100px;
margin: 0 auto;
padding: 0.8rem;
text-align: center;
cursor: default;
border-radius: 10px;
background: #607d8b33;
color: #1CA8DD;
box-shadow: 1px 1px 2px #373737;
}
.there-are-items {
height: 100%;
}
</style>
<template>
<Collapsable :title="title" :uniqueKey="groupId">
<div v-if="!items || items.length < 1" class="no-items">
No Items to Show Yet
</div>
<div v-else class="there-are-items">
<Item
v-for="item in items"
:key="`${groupId}-${item.id}`"
:id="`${groupId}-${item.id}`"
:title="item.title"
:description="item.description"
:icon="item.icon"
/>
</div>
</Collapsable>
</template>
<script>
import Item from '@/components/Item.vue';
import Collapsable from '@/components/Collapsable.vue';
export default {
name: 'ItemGroup',
props: {
groupId: String,
title: String,
items: Array,
},
components: {
Collapsable,
Item,
},
};
</script>
<style scoped lang="scss">
.no-items {
width: 100px;
margin: 0 auto;
padding: 0.8rem;
text-align: center;
cursor: default;
border-radius: 10px;
background: #607d8b33;
color: #1CA8DD;
box-shadow: 1px 1px 2px #373737;
}
.there-are-items {
height: 100%;
}
</style>

View File

@@ -1,41 +1,41 @@
<template>
<nav id="nav">
<router-link to="/" class="nav-item">Home</router-link>
<router-link to="/about" class="nav-item">About</router-link>
</nav>
</template>
<script>
export default {
name: 'Nav'
}
</script>
<style scoped lang="scss">
nav {
display: flex;
align-items: center;
.nav-item {
display: inline-block;
padding: 0.75rem 0.5rem;
margin: 0.5rem;
outline: none;
border: none;
border-radius: 5px;
background: #607d8b33;
-webkit-box-shadow: 1px 1px 2px #232323;
box-shadow: 1px 1px 2px #232323;
color: #1CA8DD;
font-family: "Comfortaa", cursive;
text-decoration: none;
&:hover {
background: #607d8b1c;
box-shadow: 1px 4px 3px #232323;
}
}
.router-link-active {
border: 1px solid #1CA8DD;
}
}
</style>
<template>
<nav id="nav">
<router-link to="/" class="nav-item">Home</router-link>
<router-link to="/about" class="nav-item">About</router-link>
</nav>
</template>
<script>
export default {
name: 'Nav',
};
</script>
<style scoped lang="scss">
nav {
display: flex;
align-items: center;
.nav-item {
display: inline-block;
padding: 0.75rem 0.5rem;
margin: 0.5rem;
outline: none;
border: none;
border-radius: 5px;
background: #607d8b33;
-webkit-box-shadow: 1px 1px 2px #232323;
box-shadow: 1px 1px 2px #232323;
color: #1CA8DD;
font-family: "Comfortaa", cursive;
text-decoration: none;
&:hover {
background: #607d8b1c;
box-shadow: 1px 4px 3px #232323;
}
}
.router-link-active {
border: 1px solid #1CA8DD;
}
}
</style>

View File

@@ -1,36 +1,36 @@
<template>
<div class="page-titles">
<h1>Pannel</h1>
<span class="subtitle">Awesome subtitle</span>
</div>
</template>
<script>
export default {
name: 'PageTitle'
}
</script>
<style scoped lang="scss">
.page-titles {
display: flex;
flex-direction: column;
h1 {
background: -webkit-linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
background: linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 3rem;
margin: 0;
}
span.subtitle {
color: #9F86FF;
font-style: italic;
text-shadow: 1px 1px 2px #130f23;
}
@media screen and (max-width: 600px) {
text-align: center;
padding: 0.25rem 0;
}
}
</style>
<template>
<div class="page-titles">
<h1>Pannel</h1>
<span class="subtitle">Awesome subtitle</span>
</div>
</template>
<script>
export default {
name: 'PageTitle',
};
</script>
<style scoped lang="scss">
.page-titles {
display: flex;
flex-direction: column;
h1 {
background: -webkit-linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
background: linear-gradient(to left top, #9F86FF, #1CA8DD, #007AE1);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 3rem;
margin: 0;
}
span.subtitle {
color: #9F86FF;
font-style: italic;
text-shadow: 1px 1px 2px #130f23;
}
@media screen and (max-width: 600px) {
text-align: center;
padding: 0.25rem 0;
}
}
</style>

View File

@@ -1,14 +1,14 @@
import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue'
import router from './router'
import './registerServiceWorker'
Vue.use(Element)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
import Vue from 'vue';
import Element from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
import router from './router';
import './registerServiceWorker';
Vue.use(Element);
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App),
}).$mount('#app');

View File

@@ -1,32 +1,32 @@
/* eslint-disable no-console */
import { register } from 'register-service-worker'
import { register } from 'register-service-worker';
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
ready() {
console.log(
'App is being served from cache by a service worker.\n' +
'For more details, visit https://goo.gl/AFskqB'
)
'App is being served from cache by a service worker.\n'
+ 'For more details, visit https://goo.gl/AFskqB',
);
},
registered () {
console.log('Service worker has been registered.')
registered() {
console.log('Service worker has been registered.');
},
cached () {
console.log('Content has been cached for offline use.')
cached() {
console.log('Content has been cached for offline use.');
},
updatefound () {
console.log('New content is downloading.')
updatefound() {
console.log('New content is downloading.');
},
updated () {
console.log('New content is available; please refresh.')
updated() {
console.log('New content is available; please refresh.');
},
offline () {
console.log('No internet connection found. App is running in offline mode.')
offline() {
console.log('No internet connection found. App is running in offline mode.');
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
error(error) {
console.error('Error during service worker registration:', error);
},
});
}

View File

@@ -1,15 +1,15 @@
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
Vue.use(Router)
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
component: Home,
},
{
path: '/about',
@@ -17,7 +17,7 @@ export default new Router({
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
}
]
})
component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
},
],
});

View File

@@ -17,47 +17,45 @@
<script>
import Header from '@/components/Header.vue'
import FilterTile from '@/components/FilterTile.vue'
import ItemGroup from '@/components/ItemGroup.vue'
import * as linkData from './../data/item-data.json'
import Header from '@/components/Header.vue';
import FilterTile from '@/components/FilterTile.vue';
import ItemGroup from '@/components/ItemGroup.vue';
import * as linkData from '../data/item-data.json';
export default {
name: 'home',
props: {
title: { default: 'Panel', type: String },
subtitle: { default: 'All your server management tools in one place', type: String }
subtitle: { default: 'All your server management tools in one place', type: String },
},
components: {
Header,
FilterTile,
ItemGroup
},
data: () => {
return {
items: linkData.default,
searchTile: ''
}
ItemGroup,
},
data: () => ({
items: linkData.default,
searchTile: '',
}),
methods: {
searching (searchTile) {
this.searchTile = searchTile
searching(searchTile) {
this.searchTile = searchTile;
},
getDomainFromUrl (url) {
var urlPattern = /^(?:https?:\/\/)?(?:w{3}\.)?([a-z\d\.-]+)\.(?:[a-z\.]{2,10})(?:[/\w\.-]*)*/;
var domainPattern = url.match(urlPattern);
return domainPattern? domainPattern[1] : ''
getDomainFromUrl(url) {
const urlPattern = /^(?:https?:\/\/)?(?:w{3}\.)?([a-z\d.-]+)\.(?:[a-z.]{2,10})(?:[/\w.-]*)*/;
const domainPattern = url.match(urlPattern);
return domainPattern ? domainPattern[1] : '';
},
filterTiles (allTiles) {
return allTiles.filter(tile => {
const searchTerm = this.searchTile.toLowerCase()
return tile.title.toLowerCase().includes(searchTerm) ||
tile.provider.toLowerCase().includes(searchTerm) ||
this.getDomainFromUrl(tile.url).includes(searchTerm)
})
}
}
}
filterTiles(allTiles) {
return allTiles.filter((tile) => {
const searchTerm = this.searchTile.toLowerCase();
return tile.title.toLowerCase().includes(searchTerm)
|| tile.provider.toLowerCase().includes(searchTerm)
|| this.getDomainFromUrl(tile.url).includes(searchTerm);
});
},
},
};
</script>
<style lang="scss" scoped>