Moved functions from view to component, and added filters

This commit is contained in:
Alexis
2021-03-06 23:35:23 +01:00
parent 2a0858d76f
commit 1c21c53ef0
3 changed files with 195 additions and 51 deletions

View File

@@ -0,0 +1,120 @@
<template>
<div class="celestial-filters">
<ul class="no-style">
<li>
<button
class="btn btn-primary"
:class="[filters.all ? 'active' : '']"
@click="emitFilter('all')"
>
Tous
</button>
<button
class="btn btn-primary btn-icon"
:class="[filters.planets ? 'active' : '']"
@click="emitFilter('planets')"
>
Planètes
<img
src="icons/saturn-planet-shape-white.svg"
alt=""
class="fs-icon icon-sm"
/>
</button>
<button
class="btn btn-primary btn-icon"
:class="[filters.moons ? 'active' : '']"
@click="emitFilter('moons')"
>
Lunes
<img
src="icons/moon-and-stars-in-a-cloud-white.svg"
alt=""
class="fs-icon icon-sm"
/>
</button>
<button
class="btn btn-primary btn-icon"
:class="[filters.stars ? 'active' : '']"
@click="emitFilter('stars')"
>
Etoiles
<img src="icons/sun-shape-white.svg" alt="" class="fs-icon icon-sm" />
</button>
<button
class="btn btn-primary btn-icon"
:class="[filters.others ? 'active' : '']"
@click="emitFilter('others')"
>
Autres
<img
src="icons/stars-group-white.svg"
alt=""
class="fs-icon icon-sm"
/>
</button>
</li>
</ul>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "celestial-filters",
props: {
celestials: {
type: Array
}
},
data() {
return {
filters: {
all: false,
planets: false,
moons: false,
stars: false,
others: false
}
};
},
methods: {
/**
* Emits the type of celestial body to filter for to parent
*/
emitFilter(type: string) {
// Reset filter appearance
this.filters = {
all: false,
planets: false,
moons: false,
stars: false,
others: false
};
// Triggers the correct filter
if (type == "all") {
this.filters.all = true;
} else if (type == "planets") {
this.filters.planets = true;
} else if (type == "moons") {
this.filters.moons = true;
} else if (type == "stars") {
this.filters.stars = true;
} else if (type == "others") {
this.filters.others = true;
}
// Emit filter type
this.$emit("filter:celestials", type);
}
}
});
</script>
<style lang="scss" scoped>
.celestial-filters {
margin-bottom: 20px;
}
</style>

View File

@@ -1,8 +1,9 @@
<template> <template>
<div class="celestial-list-wrapper"> <div class="celestial-list-wrapper">
<celestial-filters @filter:celestials="filterCelestials" />
<ul v-if="celestials" class="celestial-list grid no-style"> <ul v-if="celestials" class="celestial-list grid no-style">
<li <li
v-for="(celestial, index) in celestials" v-for="(celestial, index) in sortedCelestials"
:key="index" :key="index"
class="celestial-item" class="celestial-item"
> >
@@ -15,16 +16,83 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from "vue"; import { defineComponent } from "vue";
// API
import axios from "axios";
// Global methods
import { addCelestialType } from "@/plugins/methods";
import CelestialCard from "@/components/celestials/CelestialCard.vue"; import CelestialCard from "@/components/celestials/CelestialCard.vue";
import CelestialFilters from "./CelestialFilters.vue";
export default defineComponent({ export default defineComponent({
name: "celestial-list", name: "celestial-list",
components: { components: {
CelestialCard CelestialCard,
CelestialFilters
}, },
props: {
celestials: { // Initial state
type: Array data() {
return {
celestials: Array<any>(),
activeFilter: "all"
};
},
computed: {
sortedCelestials(): any {
if (this.activeFilter == "moons") {
return this.celestials.filter(e => e.type === "lune");
} else if (this.activeFilter == "planets") {
return this.celestials.filter(
e => e.type === "planète" || e.type === "planète à lunes"
);
} else if (this.activeFilter == "stars") {
return this.celestials.filter(e => e.type === "étoile");
} else if (this.activeFilter == "others") {
return this.celestials.filter(e => e.type === "autre");
} else {
return this.celestials;
}
}
},
mounted() {
// Fetches from API...
this.fetchCelestials().then(res => {
// ...and add type
this.celestials = this.addType(res);
});
},
methods: {
/**
* Fetches celestial bodies from API
*/
fetchCelestials(): Promise<any> {
return axios
.get("https://api.le-systeme-solaire.net/rest/bodies/")
.then(res => {
return res.data.bodies;
})
.catch(err => {
console.log(err);
return [];
});
},
/**
* Assign a type from the celestial object provided
*/
addType(bodies: Array<any>): Array<any> {
return bodies.map((e: any) => addCelestialType(e));
},
/**
* Applies the filter type to the data
*/
filterCelestials(type: string) {
this.activeFilter = type;
} }
} }
}); });

View File

@@ -4,7 +4,7 @@
<h1 class="heading-1">Le système solaire</h1> <h1 class="heading-1">Le système solaire</h1>
</header> </header>
<div class="section-content"> <div class="section-content">
<celestials-list :celestials="celestials" /> <celestials-list />
</div> </div>
</section> </section>
</template> </template>
@@ -13,54 +13,10 @@
import { defineComponent } from "vue"; import { defineComponent } from "vue";
import CelestialsList from "@/components/celestials/CelestialsList.vue"; import CelestialsList from "@/components/celestials/CelestialsList.vue";
// API
import axios from "axios";
// Global methods
import { addCelestialType } from "@/plugins/methods";
export default defineComponent({ export default defineComponent({
name: "Celestials", name: "Celestials",
components: { components: {
CelestialsList CelestialsList
},
// Initial state
data() {
return {
celestials: Array<any>()
};
},
mounted() {
// Fetches from API...
this.fetchCelestials().then(res => {
// ...and add type
this.celestials = this.addType(res);
});
},
methods: {
/**
* Fetches celestial bodies from API
*/
fetchCelestials(): Promise<any> {
return axios
.get("https://api.le-systeme-solaire.net/rest/bodies/")
.then(res => {
return res.data.bodies;
})
.catch(err => {
console.log(err);
return [];
});
},
/**
* Assign a type from the celestial object provided
*/
addType(bodies: Array<any>): Array<any> {
return bodies.map((e: any) => addCelestialType(e));
}
} }
}); });
</script> </script>
@@ -69,7 +25,7 @@ export default defineComponent({
.celestials { .celestials {
position: relative; position: relative;
min-height: 100%; min-height: 100%;
padding: 25px 10%; padding: 25px 5%;
&:after { &:after {
display: block; display: block;